0

2 人間で original_message を送信したい。アリスとボブとしましょう。これらの手順が署名の検証に正しいかどうかを知りたいです。

  1. Alice は自分の PrivateKey で original_message をハッシュします -> h(m)
  2. アリスはハッシュ化されたメッセージを暗号化します -> c(h(m))
  3. Alice は自分の PrivateKey でメッセージに署名します -> s(c(h(m)))

Alice は最終的に署名されたメッセージ (PublicKey) と (original_message) を Bob に送信します。ボブ側:

  1. Bob は original_message をハッシュします -> h(m)
  2. ボブは署名されたメッセージをアリスの公開鍵で解読します -> d(s(c(h(m))))
  3. それらが等しいかどうかボブはハッシュされたメッセージで解読されたメッセージをチェックしますか? もし ( h(m) == d(s(c(h(m)))) )

私はいくつかの間違いをしていることを知っています。両側の正しい順序を知っている人はいますか?

ここでは、これを行うために java.security を使用しましたが、最終ステップでハッシュをチェックすると、 false が返されます!

アリスの部分で:

public byte[] Sign(byte[] aMessage) {

        try {
            // get an instance of a cipher with RSA with ENCRYPT_MODE
            // Init the signature with the private key
            // Compute signature
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, thePrivateKey);

            Signature instance = Signature.getInstance("MD5withRSA");
            instance.initSign(thePrivateKey);

            // get an instance of the java.security.MessageDigest with MD5
            // process the digest
            MessageDigest md5_digest = MessageDigest.getInstance("MD5");
            md5_digest.update(aMessage);
            byte[] digest = md5_digest.digest();

            // return the encrypted digest
            byte[] cipherText = cipher.doFinal(digest);

            instance.update(cipherText);            
            byte[] signedMSG = instance.sign();

            return signedMSG;

        } catch (Exception e) {
            System.out.println("Signature error");
            e.printStackTrace();
            return null;
        }

    }

ボブの部分で:

public boolean CheckSignature(byte[] aMessage, byte[] aSignature,
            PublicKey aPK) {
        try {
            // get an instance of a cipher with RSA with ENCRYPT_MODE
            // Init the signature with the private key
            // decrypt the signature
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, aPK);
            byte[] decrypted_digest =  cipher.doFinal(aSignature);

            // get an instance of the java.security.MessageDigest with MD5
            MessageDigest md5_digest = MessageDigest.getInstance("MD5");

            // process the digest
            md5_digest.update(aMessage);
            byte[] digest = md5_digest.digest();

            // check if digest1 == digest2
            if (decrypted_digest == digest) {
                return true;
            }else {
                return false;
            }

        } catch (Exception e) {
            System.out.println("Verify signature error");
            e.printStackTrace();
            return false;
        }
    }
4

2 に答える 2

0

最後に答えを見つけました。間違いは、アリスの部分で sign() を実行していたことです。ハッシュと暗号化を行っているときはすでに署名になっており、ボブの側でもう一度 sign() すると、ハッシュされた署名を回復することができなくなったためです。

私のコードは、「Java セキュリティ公開鍵暗号化における一方向ハッシュ」の良い例でもあります。

これは Alice 部分の変更であり、その後はすべて機能します。

public byte[] Sign(byte[] aMessage) {

        try {
            // get an instance of a cipher with RSA with ENCRYPT_MODE
            // Init the signature with the private key
            // Compute signature
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, thePrivateKey);

            // get an instance of the java.security.MessageDigest with MD5
            // process the digest
            MessageDigest md5_digest = MessageDigest.getInstance("MD5");
            byte[] digest = md5_digest.digest(aMessage);

            // return the encrypted digest
            byte[] cipherText = cipher.doFinal(digest);

            return cipherText;

        } catch (Exception e) {
            System.out.println("Signature error");
            e.printStackTrace();
            return null;
        }

    }
于 2014-01-09T10:28:15.803 に答える