Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/402.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.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#_Rsa - Fatal编程技术网

在Java中从C#解密RSA加密数据。加密数据的格式?

在Java中从C#解密RSA加密数据。加密数据的格式?,java,c#,rsa,Java,C#,Rsa,我正在使用RSA加密对C#中的一些数据进行加密。现在我想用Java解密加密的数据。 但我遇到了一些问题 主要问题可能是从c#到java获取加密消息。 在c#中,我们有无符号字节,而endian是不同的 因此,为了进行测试,我将c#中加密数据的byte数组转换为sbyte数组,并获得它的字符串表示形式。 然后将字节数组的字符串表示形式复制到java代码中,并将其转换回“字节”数组。之后,我反转数组以匹配java的endianess 但如果我尝试解码上面传输的数据,我会得到以下异常: javax.c

我正在使用RSA加密对C#中的一些数据进行加密。现在我想用Java解密加密的数据。 但我遇到了一些问题

主要问题可能是从c#到java获取加密消息。 在c#中,我们有无符号字节,而endian是不同的

因此,为了进行测试,我将c#中加密数据的
byte
数组转换为
sbyte
数组,并获得它的字符串表示形式。 然后将字节数组的字符串表示形式复制到java代码中,并将其转换回“字节”数组。之后,我反转数组以匹配java的endianess

但如果我尝试解码上面传输的数据,我会得到以下异常:

javax.crypto.BadPaddingException:消息大于模数

从C#到C#的加密和解密与从java到java的加密和解密一样有效。只有C#to java无法工作。(要加密的字符串长度为7个字符,因此它实际上并不太长)

我正在将c#中的公钥转换为
BigInteger
。公钥是从
参数
传递的:

 public byte[] RSAEncrypt(byte[] data, RSAParameters param, bool padding) {
        using (RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024)) {
            rsaProvider.ImportParameters(param);

            byte[] modulusArray = param.Modulus;
            byte[] exponentArray = param.Exponent;

            BigInteger modulusBigInt = new BigInteger(modulusArray);

            BigInteger exponentBigInt = new BigInteger(exponentArray);

            encryptedData = rsaProvider.Encrypt(data, false);

            return encryptedData;
        }
    }
之后,我将模和指数的字符串表示形式复制到java代码中,并从中创建新的
biginger
,然后创建公钥:

    BigInteger modulusBigInt = new BigInteger(modulusBytesStr);
    BigInteger exponentBigInt = getBigIntFromByteString(exponentBytesStr);

    Key pK = getPublicKey(modulusBigInt, exponentBigInt);
然后我尝试解密数据(其中数据是我从c#传输到java的字节数组,如上所述):

但是如果我尝试这样做,我会得到上面提到的例外。我认为公钥应该是正确的。至少我在c#和java中有相同的
biginger
模和指数值。填充也是相等的。 所以我假设加密数据的格式有问题。它应该有哪个fromat

我亦看过这项质询: 但即使在那之后,我也不确定要加密/解密的数据应该采用什么格式

编辑:尝试将c#中的加密字节转换为
Base64字符串
,并在java中将其转换回字节。也不起作用

EDIT2:如果我使用的是
var key=rsaProvider.ToXmlString(true)
获取公钥的xml表示,并将模和指数的xml字符串放入java代码中,将它们从Base64字符串转换为字节数组,从字节数组转换为BigInteger,然后获得模的BigInteger的另一个值,就像c#中的BigInteger一样,但我得到了如下异常值:
javax.crypto.BadPaddingException:Decryption error

EDIT3:发现我的错误:对于简单的测试,我只是使用我在C#代码中生成的私钥在java中解密。但是在我的java代码中,我试图从私钥生成公钥

     RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);

        KeyFactory kf = KeyFactory.getInstance("RSA");
        PublicKey pK = kf.generatePublic(keySpec);
这显然是错误的。所以我把它改成:

 RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulusBigInt, exponentBigInt);

        KeyFactory kf = KeyFactory.getInstance("RSA");
        Key key = kf.generatePrivate(keySpec);
它成功了。这也是GregS方法起作用的原因(没有生成“PublicKey”/“PrivateKey”,解密也没有使用java内置方法)

因此,为了进行测试,我将c#中加密数据的字节数组转换为sbyte数组,并获得它的字符串表示形式。然后将字节数组的字符串表示形式复制到java代码中,并将其转换回“字节”数组。之后,我反转数组以匹配java的endianess


我不太明白为什么“持久性”在这里是个问题。Endianism是您运行的CPU的函数,而不是编程语言。

我有点不清楚您到底出了什么问题。下面是一个基于您的代码的示例。我没有windows机器,所以我用Mono测试了这个

C#:

使用系统;
使用System.Security.Cryptography;
使用系统文本;
名称空间RsaDotNetToJava
{
类主类
{
公共字节[]RSA加密(字节[]数据、RSA参数参数、布尔填充){
使用(rsacryptserviceprovider rsaProvider=新的rsacryptserviceprovider(1024)){
rsaProvider.ImportParameters(参数);
var encryptedData=rsaProvider.Encrypt(数据,false);
返回加密数据;
}
}
公共静态void W(字符串标签,字节[]x){
var b64=Convert.tobase64字符串(x);
Console.WriteLine(“{0}={1}”,标签,b64);
}
公共静态void Main(字符串[]args)
{
var x=新的MainClass();
var rsa=新的rsacyptoserviceprovider(1024);
var data=Encoding.ASCII.GetBytes(“Hello world”);
var parms=rsa.ExportParameters(true);
W(“模量”,参数模量);
W(“P”,参数P);
W(“指数”,参数D);
W(“指数”,参数指数);
var cipher=x.rsa加密(数据、参数、假);
W(“密码”,Cipher);
}
}
}
接下来,一些Java从命令行读取带有(“label=”stripped off)的base64字符串并执行一些操作。它使用Java7类
javax.xml.bind.DatatypeConverter
作为base64解析器

import java.math.biginger;
导入javax.xml.bind.DatatypeConverter;
公共类JavaToDotNet{
私有静态BigInteger B64ToBiginger(字符串b64){
byte[]bigEndianBytes=DatatypeConverter.parseBase64Binary(b64);
返回新的biginger(1,bigEndianBytes);
}
/**
*@param args base64编码的.NET大端整数数组
*args[0]=模数
*args[1]=素数
*args[2]=解密指数
*args[3]=加密指数
*args[4]=密码
*@抛出异常
*/
公共静态void main(字符串[]args)引发异常{
BigInteger模数=B64ToBiginger(args[0]);
最终整数模BYTELENGTH=(模.位长()+7)/8;
BigInteger素数=B64ToBiginger(参数[1]);
大整数d
 RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulusBigInt, exponentBigInt);

        KeyFactory kf = KeyFactory.getInstance("RSA");
        Key key = kf.generatePrivate(keySpec);