Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#dons'中创建的数字签名;Java验证中的t匹配_Java_C#_Rsa_Digital Signature - Fatal编程技术网

在C#dons'中创建的数字签名;Java验证中的t匹配

在C#dons'中创建的数字签名;Java验证中的t匹配,java,c#,rsa,digital-signature,Java,C#,Rsa,Digital Signature,我需要在使用“SHA1 WithRSA”的JAVA程序中使用“SHA1”算法验证从C#创建的签名。签名字节不匹配。我使用C#程序生成的公钥来验证存储在文件中的签名。我对密码学一无所知。下面是创建签名的C#代码: RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSA.FromXmlString(privateKey); var encoder = new UTF8En

我需要在使用“SHA1 WithRSA”的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);
//读取xml文件以获取模数和指数字节
文件publicKeyFileQA=新文件(PUBLIC_KEY_File_QA);
映射PublicKeyModulesExponentValues=DSXCRM_3YBP_Global_WebServicesUtil.readXMLFile(publicKeyFileQA);
BigInteger PublicKeyModules=PublicKeyModulesExponentValues.get(“模数”);
BigInteger publicKeyExponent=PublicKeyModulesExponentValues.get(“指数”);
System.out.println(“BigInteger模数:+PublicKeyModules+”BigInteger指数:+PublicKeyIndex”);
String messageWithSignature=(String)mapDataToPost.get(“SignedMessage”);
String encryptedMessage=(String)mapDataToPost.get(“encryptedMessage”);
byte[]signatureBytes=DatatypeConverter.parseBase64Binary(messageWithSignature);
System.out.println(“签名字节:”+新字符串(signatureBytes));
字节[]cipherMessage=DatatypeConverter.parseBase64Binary(encryptedMessage);
System.out.println(“密码消息:+新字符串(cipherMessage));
KeyFactory KeyFactory=KeyFactory.getInstance(KEY_算法);
RSAPublicKeySpec publicKeySpec=新的RSAPublicKeySpec(PublicKeyModule,publicKeyExponent);
PublicKey PublicKey=keyFactory.generatePublic(publicKeySpec);
Signature sig=Signature.getInstance(“SHA1withRSA”);
sig.initVerify(公钥)//发送方公钥
信号更新(加密信息);
布尔值isRightSender=sig.verify(signatureBytes);
System.out.println(“isRightSender:+isRightSender”);

但匹配签名的结果是错误的。我不明白什么是错的。你能提供一些建议吗。有没有其他与C#和JAVA兼容的算法具有相同的签名?谢谢

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

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

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

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中是相同的;因此,一旦您将数据传输安排好,一切都应该工作。

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

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

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

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中是相同的;因此,一旦您将数据传输安排好,一切都应该正常。

我看不到您的代码中有明显的错误。可能是从C#发送到Java的消息和签名字节的编码?是的,我同意你的看法。这可能是我面临的一些编码问题。我看不到您的代码中有明显的错误。可能是从C#发送到Java的消息和签名字节的编码?是的,我同意你的看法。这可能是我面临的一些编码问题。我尝试了上面的部分,问题是在java中将base64字符串解析为byte[]之后,它和我们从C#中得到的不一样。我正在使用DatatypeConverter.parseBase64Binary(messageWithSignature);我得到了一个正确的方向,我只需要使用base64字符串来从C#到java转换成字节[],因为C#和java之间没有其他格式兼容,我接受你的答案。然而,我有一些签名不匹配的困难。@Coder你确定你正确地构建了
publicKey
?特别是,BigInteger可能会将高位设置为负数的任何内容解释为负数。检查它是否测试为小于biginger.zeroYes,因为当C#程序使用Java程序生成的公钥加密数据和私钥解密数据时,它工作正常。所以理想情况下签名也应该匹配。我试过上面的部分,问题是在java中将base64字符串解析为byte[]之后,它和我们从C#中得到的不一样。我正在使用DatatypeConverter.parseBase64Binary(messageWithSignature);我得到了一个正确的方向,我只需要使用base64字符串来从C#到java转换成字节[],因为C#和java之间没有其他格式兼容,我接受你的答案。然而,我有一些签名不匹配的困难。@Coder你确定你正确地构建了
publicKey
?特别是,BigInteger可能会将高位设置为负数的任何内容解释为负数。检查它是否测试为小于BigInteger.zeroYes,