0


メッセージに署名するための次のコードを作成し、Bouncy Castle の Java で検証します。
署名は正しく機能しますが、検証は機能しません。コード出力の結果:
改ざんされた署名
は回復できず
、null を返します。
eng.hasFullMessage() 関数が false を返すのはなぜですか? また、次のコードが機能しないのはなぜですか?
皆さんありがとう。

 
public static String sigVer(PublicKey pu, PrivateKey pr, String original) throws Exception{
        //sign
        BigInteger big = ((RSAKey) pu).getModulus();
byte[] text = original.getBytes();
RSAKeyParameters rsaPriv = new RSAKeyParameters(true, big,((RSAPrivateKey) pr).getPrivateExponent()); RSAKeyParameters rsaPublic = new RSAKeyParameters(false, big,((RSAPublicKey) pu).getPublicExponent()); RSAEngine rsa = new RSAEngine(); byte[] data; Digest dig = new SHA1Digest(); ISO9796d2Signer eng = new ISO9796d2Signer(rsa, dig, true); eng.init(true, rsaPriv); eng.update(text[0]); eng.update(text, 1, text.length - 1);
data = eng.generateSignature(); String signature = data.toString(); //verify eng = new ISO9796d2Signer(rsa, dig, true); eng.init(false, rsaPublic); text = signature.getBytes(); if (!eng.verifySignature(text)) { System.out.println("signature tampered"); } try{ if (eng.hasFullMessage()) { eng.updateWithRecoveredMessage(signature.getBytes());
} byte[] message = eng.getRecoveredMessage(); String ss = message.toString(); return ss; } catch (Exception e) { System.out.println("can not recover"); return null;
}

}
4

3 に答える 3

0

実際に大きなメッセージを検証するには、完全な回復のためにのみ機能する署名だけでなく、元のメッセージである検証のための入力を提供する必要があります

//verify
eng = new ISO9796d2Signer(rsa, dig, true);
eng.init(false, rsaPublic);

// when verifying there has to be also the original plain text
eng.update(text,0,text.length);

signBytes = signature.getBytes(); 
if (!eng.verifySignature(signBytes)) {
     System.out.println("signature tampered");
}
于 2013-03-18T21:47:15.637 に答える
0

私はこの方法で遊んで、エラーも受け取りました。さらに、前述の「更新」メソッドは機能せず、「updateWithRecoveredMessage」は存在しません。

いくつかのテストの後、私は次のように考えました:

  • getBytes("UTF-8") と String s = new String(message, "UTF-8") を訴える必要があります
  • 署名には最大 234 バイトを使用できますが、235 バイトでは壊れます。(256バイトになると思いますが、一部はパディング/マーカーに使用されます)

私が正しく理解していれば、問題は、署名者が特定の量のバイトのみを署名に含めることを許可していることです。

より長いペイロードを使用する場合は、検証ステップにもペイロードを含める必要があります。

    eng.init(false, rsaPublic);
    byte[] message = payload.getBytes("UTF-8");
    eng.update(message, 0, message.length);

その後、検証は正常に機能し、eng.getRecoveredMessage() でペイロードの最初の部分を取得します。

私にとって、これは目的を達成できなかったので、別の方法に進みました。

私が使用する回避策は、2 段階のアプローチです。

1) 署名に保存される短いキーを生成します。2) 対称 (AES) を使用して大きなペイロードを暗号化します。ペイロードのハッシュも生成します。3) ペイロードのキーとハッシュは、署名に含まれているものです。

于 2013-12-29T10:25:32.863 に答える