签署消息并通过Bouncy Castle的恢复消息进行验证

时间:2012-07-10 13:07:25

标签: java digital-signature bouncycastle


我编写了以下用于签名消息的代码,然后在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;
}

}

3 个答案:

答案 0 :(得分: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");
}

答案 1 :(得分:0)

我玩这种方法并且还收到错误。另外,提到的“update”方法不起作用,并且“updateWithRecoveredMessage”不存在。

经过一些测试,我认为:

  • 我必须起诉getBytes(“UTF-8”)和String s = new String(消息,“UTF-8”)
  • 我可以在签名中使用最多234个字节,其中235将会中断。 (猜测它将是256字节,但有些用于填充/标记)

如果我理解正确,问题是签名者只允许在签名中包含一定数量的字节。

如果使用更长的有效负载,则必须在验证步骤中包含有效负载:

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

然后验证工作正常,您可以使用eng.getRecoveredMessage()获取有效负载的第一部分。

对我而言,这打败了目的,所以我采取了另一种方式。

我使用的解决方法是两步两步:

1)我生成一个存储在签名中的短密钥 2)使用对称(即AES)来加密大有效载荷。我还为有效负载生成哈希。 3)有效载荷的密钥和散列是签名中包含的密钥和散列。

答案 2 :(得分:0)

在大多数情况下,我们没有原始消息来通过签名进行更新和验证。另一方面,长度限制为234个字节。