sign the message and verify with recover message by Bouncy Castle

五迷三道 提交于 2019-12-08 14:48:39

问题



I write the following code for signing the message and then verify it, in java by Bouncy Castle.
signing work properly but verifying not work. the result of code print:
signature tampered
can not recover
and return null.
why eng.hasFullMessage() function return false and why the following code doesn't work?
thanks all.

 
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;
} }

回答1:


Actually to verify large messages you have to provide the input for verification which is the original message and not only the signature which works only for full recovery

//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");
}



回答2:


I played around with this method and also receive the errors. In addition the "update" method mentioned does not work and the "updateWithRecoveredMessage" does not exist.

After some testing I figured that:

  • I have to sue getBytes("UTF-8") and String s = new String(message, "UTF-8")
  • I can use up to 234 bytes in the signature, with 235 it will break. (guess it would be 256 bytes but some are used for padding/markers)

If I understand correctly the problem is that the signer only allows a certain amount of bytes to be included in the signature.

If you use a longer payload you MUST include the payload in the verification step as well:

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

then verification works just fine and you get the first part of the payload with eng.getRecoveredMessage().

For me this defeated the purpose, so I went another way.

The workaround I use is to two a two-step approach:

1) I generate a short key which is stored in the signature 2) use a symmetric (i.e. AES) to encrypt the large payload. I also generate a hash for the payload. 3) the key and hash for the payload is the one included in the signature.




回答3:


Most of the times we don't have the original message to update and verifiy by the signature. On the other hand the length is limited to 234 bytes.



来源:https://stackoverflow.com/questions/11413980/sign-the-message-and-verify-with-recover-message-by-bouncy-castle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!