Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.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
在java中从C#验证rsa签名_Java_C#_Encryption_Cryptography_Rsa - Fatal编程技术网

在java中从C#验证rsa签名

在java中从C#验证rsa签名,java,c#,encryption,cryptography,rsa,Java,C#,Encryption,Cryptography,Rsa,我试图在服务器应用程序(用C#编写)上生成RSA SHA512签名,并在客户端应用程序(用Java编写)上验证该签名。在签名交换之前,服务器生成公钥和私钥对,并通过为客户端应用程序提供生成的模数和指数值,与客户端应用程序共享公钥。当签名需要验证时,客户端应用程序将存储值以供以后使用 服务器正在生成128字节模数和128字节签名。我只是在测试时使用[0x00,0x01,0x02,0x03]的字节数组作为签名的源数据 出于某种原因,我的Java应用程序在验证签名时总是失败 我的C代码(创建签名):

我试图在服务器应用程序(用C#编写)上生成RSA SHA512签名,并在客户端应用程序(用Java编写)上验证该签名。在签名交换之前,服务器生成公钥和私钥对,并通过为客户端应用程序提供生成的模数和指数值,与客户端应用程序共享公钥。当签名需要验证时,客户端应用程序将存储值以供以后使用

服务器正在生成128字节模数和128字节签名。我只是在测试时使用[0x00,0x01,0x02,0x03]的字节数组作为签名的源数据

出于某种原因,我的Java应用程序在验证签名时总是失败

我的C代码(创建签名):

C#端的crypto对象来自System.Security.Cryptography命名空间,java端来自java.Security


字节通过web服务和base64字符串在应用程序之间传递。我已经检查并打印了字节数组本身的值,以确保两个应用程序之间的指数、模和签名的值是正确的。两种语言/应用程序之间的签名不兼容有什么原因吗?有没有我遗漏的参数?我用SHA512实现了这两个签名,但可能还需要考虑签名的其他方面?

在C#端的XML表示中,数据存储为未签名的big-endian(和Base64编码)

但是,Java构造函数希望数据是有符号的(两个的补码)大端

因此必须使用-constructor,它期望第一个参数中的符号和第二个参数中的数据为无符号的big-endian,即需要进行以下更改:

RSAPublicKeySpec spec = new RSAPublicKeySpec(new BigInteger(1, modulus), new BigInteger(1, exponent));

您在C#中签名的数据是1、2、3、4。您声称在Java中需要的数据是0、1、2、3。@PresidentJamesMoveonPolk woops,我更新了示例代码来解决这个问题;谢谢你的帮助。尽管如此,这些数组的签名仍然失败。
getStoredExponent
getStoredModulus
未在Java代码中定义。假设两种方法仅对密钥的相应数据执行Base64解码,则模数和指数将被解释为无符号值,并分别转换为
BigInteger
new BigInteger(1,模数)
new BigInteger(1,指数)
。有了这个,验证就可以在我的机器上运行(使用我自己的测试密钥)。@Topaco你是有史以来最了不起的人!BigInteger上的1参数正是所需的参数。我想因为这些值来自C#(它使用无符号),所以我需要那个值。
byte[] expectedData = new byte[4];
expectedData[0] = 0;
expectedData[1] = 1;
expectedData[2] = 2;
expectedData[3] = 3;

byte[] exponent = getStoredExponent(); // three-byte value from server
byte[] modulus = getStoredModulus(); // 128-byte value from server

RSAPublicKeySpec spec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(exponent));
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(spec);

Signature verifier = Signature.getInstance("SHA512withRSA");
verifier.initVerify(publicKey);
verifier.update(expectedData);

if(verifier.verify(signature)) {
  System.out.println("signature verified");
} else {
  System.out.println("signature failed verification"); // always ends up here :(
}
RSAPublicKeySpec spec = new RSAPublicKeySpec(new BigInteger(1, modulus), new BigInteger(1, exponent));