繁体   English   中英

在C#中创建的数字签名在Java验证中不匹配

[英]Digital Signature created in C# doesn't match in Java verification

我需要在使用“SHA1withRSA”的JAVA程序中使用“SHA1”算法验证从C#创建的签名。签名字节不匹配。 我正在使用C#程序生成的公钥来验证存储在文件中的签名。 我是密码学的新手。 下面是创建签名的C#代码:

        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

        RSA.FromXmlString(privateKey);

        var encoder = new UTF8Encoding();
        byte[] originalData = encoder.GetBytes(message);
        SHA1 sha1 = SHA1.Create();

        byte[] signedBytes = RSA.SignData(originalData, sha1);

        return signedBytes;

我试图在Java程序中验证签名如下:

   //read xml file to get modulus and exponent bytes
            File publicKeyFileQA = new File(PUBLIC_KEY_FILE_QA);

            Map<String, BigInteger> publicKeyModulusExponentValues = DSXCRM_3YBP_Global_WebServicesUtil.readXMLFile(publicKeyFileQA);

            BigInteger publicKeyModulus = publicKeyModulusExponentValues.get("modulus");
            BigInteger publicKeyExponent = publicKeyModulusExponentValues.get("exponent");

            System.out.println("BigInteger Modulus : "+ publicKeyModulus + "BigInteger Exponent : " + publicKeyExponent);

            String messageWithSignature = (String) mapDataToPost.get("SignedMessage");
            String encryptedMessage = (String) mapDataToPost.get("EncryptedMessage");

            byte[] signatureBytes = DatatypeConverter.parseBase64Binary(messageWithSignature);

            System.out.println("Signature bytes : "+ new String(signatureBytes));


            byte[] cipherMessage = DatatypeConverter.parseBase64Binary(encryptedMessage);

            System.out.println("Cipher Message : "+ new String(cipherMessage));

            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(publicKeyModulus, publicKeyExponent);
            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
            Signature sig = Signature.getInstance("SHA1withRSA");
            sig.initVerify(publicKey); //public key of sender
            sig.update(cipherMessage);

            boolean isRightSender = sig.verify(signatureBytes);
            System.out.println("isRightSender : "+isRightSender);

但匹配签名的结果是错误的。 我没有弄错。 你能提供任何建议吗? 有没有其他算法兼容C#和JAVA以获得相同的签名? 谢谢!

您正在读取名为“SignedMessage”的字段,将其存储在名为“messageWithSignature”的变量中,然后将其视为仅仅是签名。 该blob中实际存在哪些数据?

您正在进一步打印二进制数据,就好像它是文本一样(通过new String(byte[]) )。 您应该在两侧打印Base64或hex,以查看它们是否匹配,对于消息字节(在验证程序中似乎称为cipherMessage )和签名。

如果你切换到静态数据(以避免在读取时计算换行符),那么它应该是有效的

byte[] originalData = Encoding.UTF8.GetBytes("This is a static message test.");
Console.WriteLine(Convert.ToBase64String(rsa.SignData(originalData), "SHA1"));

然后获取该输出,将其放入Java程序并验证

byte[] originalData = "This is a static message test.".getBytes("UTF-8");
byte[] signature = Base64.getDecoder().decode(theOutputFromTheCSharpProgram);
Signature verifier = new Signature("SHA1withRSA");
verifier.initVerify(publicKey);
verifier.update(originalData);
System.out.println(verifier.verify(signature));

如果该部分不起作用,那么您不得忠实地代表双方的相同密钥。

RSA签名的二进制格式在C#和Java中是相同的; 所以一旦你把数据传输排好了,一切都应该有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM