RSA .NET 加密 Java 解密

时间:2023-01-15
本文介绍了RSA .NET 加密 Java 解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我正在尝试使用 RSA 算法加密 .NET 中的字符串并在 Java 中解密结果.目前,我已经能够做相反的事情(在 Java 中加密,在 .NET 中解密).在这里,我的代码实际上可以工作(JAVA 加密):

<预> <代码>字节[] modulusBytes = Base64.decode( 2rRVVVFJRbH/wAPDtnwZwu + NXU + AZ6uXxh/SW + AMCBogg7vndZsnRiHoLttYYPqOyOhfgaBOQogrIfrKL4lipK4m52SBzw/FfcM9DsKs/rYR83tBLiIAfgdnVjF27tZID + HJMFTiI30mALjr7 + TFP + 2lIACXA1RIKTk7S9pDmX8 =");byte[] exponentBytes = Base64.decode("AQAB");BigInteger 模数 = 新 BigInteger(1,模数字节);BigInteger 指数 = new BigInteger(1, exponentBytes);RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(模数,指数);KeyFactory 事实 = KeyFactory.getInstance("RSA");PublicKey pubKey = fact.generatePublic(rsaPubKey);密码密码 = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.ENCRYPT_MODE, pubKey);byte[] plainBytes = new String("大猫跳舞").getBytes("UTF-8");byte[] cipherData = cipher.doFinal(plainBytes);String encryptedString = Base64.encode(cipherData);返回加密字符串;

和(.NET解密)

const int PROVIDER_RSA_FULL = 1;常量字符串 CONTAINER_NAME = "跟踪器";CspParameters cspParams;cspParams = 新的 CspParameters(PROVIDER_RSA_FULL);cspParams.KeyContainerName = CONTAINER_NAME;RSACryptoServiceProvider rsa1 = 新的 RSACryptoServiceProvider(cspParams);rsa1.FromXmlString(< RSAKeyValue><模量> 2rRVVVFJRbH/wAPDtnwZwu + NXU + AZ6uXxh/SW + AMCBogg7vndZsnRiHoLttYYPqOyOhfgaBOQogrIfrKL4lipK4m52SBzw/FfcM9DsKs/rYR83tBLiIAfgdnVjF27tZID + HJMFTiI30mALjr7 + TFP + 2lIACXA1RIKTk7S9pDmX8 = LT;/模量><指数> AQAB</指数>< P> + lXMCEwIN/7 + eMpBrq87kQppxu3jJBTwztGTfXNaPUTx + A6uqRwug5oHBbSpYXKNDNCBzVm/0VxB3bo4FJx + ZQ ==</P>< Q> yasOGaJaE9xlF9T2xRuKeG9ZxCiyjhYaYB/mbtL + SIbtkRLi/AxaU4g2Il/UxhxhSXArKxIzV28zktispPJx1Q ==</Q>< DP> ueRgQIEFUV + fY979a1RgrVHIPpqEI1URhOMH3Q59oiXCcOumM5njyIHmWQxRAzXnG +7xlKXi1PrnRll0L4oOKQ ==</DP>< DQ> dfEMNgG1HJhwpxdtmqkYuoakwQvsIRzcIAuIAJh1DoWaupWJGk8/JEstHb1d + t7uJrzrAi2KyT/HscH2diE0YQ ==</DQ>< InverseQ> YoYF9PF6FiC0YngVeaC/EQT/ea8wMYNN3YO1LuzWpcy2exPRj2U0ZbWMvHXMUb4ea2qmhZGx1QlK4ULAuWKpXQ ==</InverseQ>< d取代; g1WAWI4pEK9TA7CA2Yyy/2FzzNiu0uQCuE2TZYRNiomo96KQXpxwqAzZLw +VDXfJMypwDMAVZe/SqzSJnFEtZxjdxaEo3VLcZ1mnbIL0vS7D6iFeYutF9kF231165qGd3k2tgymNMMpY7oYKjS11Y6JqWDU0WE5hjS2X35iG6mE=</D></RSAKeyValue>");字符串 data2Decrypt = "BaB21vY+RD/jiY3AAsb269fIWTEH38s0xLUfJ7CoVUgaQ6vYzB0tiJ1Ag9HNEdCcuZdGchhqnms8jpsqsHC1iKrz6QCLsgUU7VNWDfQqZYR6Rl/GwR0biK2STnOL+g06f/JUdixHOHOgROVMqmqmqREMYK5Mpl8;byte[] encyrptedBytes = Convert.FromBase64String(data2Decrypt);byte[] plain = rsa1.Decrypt(encyrptedBytes, false);string decryptedString = System.Text.Encoding.UTF8.GetString(plain);Console.WriteLine("SALIDA:" + decryptedString);

现在我想做相反的事情......但是我遇到了一些错误,比如(密钥的大小应该是 128 字节......等等)我应该怎么做?

这里我添加当前的不工作代码:

.NET

public string Encrypt(string text){常量 int PROVIDER_RSA_FULL = 1;常量字符串 CONTAINER_NAME = "跟踪器";CspParameters cspParams;cspParams = 新的 CspParameters(PROVIDER_RSA_FULL);cspParams.KeyContainerName = CONTAINER_NAME;RSACryptoServiceProvider rsa1 = 新的 RSACryptoServiceProvider(cspParams);rsa1.FromXmlString(< RSAKeyValue><模量> 2rRVVVFJRbH/wAPDtnwZwu + NXU + AZ6uXxh/SW + AMCBogg7vndZsnRiHoLttYYPqOyOhfgaBOQogrIfrKL4lipK4m52SBzw/FfcM9DsKs/rYR83tBLiIAfgdnVjF27tZID + HJMFTiI30mALjr7 + TFP + 2lIACXA1RIKTk7S9pDmX8 = LT;/模量><指数> AQAB</指数>< P> 92jJJyzFBSx6gL4Y1YpALmc5CNjoE/wETjqb3ci2v0 + 3rZWvJKmKy1ZEdlXpyuvXVksJ6cMdUpNAkMknUk9pTQ ==</P>< Q> 4kxkABZOXyDLryYGCGY0b8N0FIdu5BTCFDYEdcatxl/f7ZGDS1NgHJpUWxkVXFfHy2Y/GuDOIbpcwlsO739H + W ==</Q>< DP> 5bNFvrdUHF + VRN45VFjNCcgQLeSkY5mBrdfASoNFGA29LM5iE5nNIMfxPCS7sQiRnq6Af6YFHVtVgJchiMvtqQ ==</DP>< DQ> J + ng1qVY5epnXlWiFIla45C7K6sNfIMvAcdwgq39KWEjeWPGyYqWXtpOtzh2eylf6Bx4GVHKBW0NPJTIJMsfLQ ==</DQ>< InverseQ> 8uu0dfPVDqB2qFM1Vdi8hl + 2uZtN7gjT2co1cEWy29HVYBZD0k9KKCf2PbkeuSfpgFpE70wW5Hrp8V7l/SwSOw ==</InverseQ>< d取代; MM/c18zroJ2Iqi9s5/asvUBF3pjO3NSEbFjFpP/NT6WdKimvECWPz2xT6NlV0Vc6tQaAAmtn7Bt + HPhfVdrA4/ysYVe3/6TWkPjW + bvAhMWu/ZqISx11/jPYSGD9g3ZXgUiqcQM8UbOjlswoq4fpheEXTB0xdVutDLpO3qgHN6k=</D></RSAKeyValue>");System.Text.UTF8Encoding 编码 = new System.Text.UTF8Encoding();byte[] textBytes = encoding.GetBytes(text);byte[] encryptedOutput = rsa1.Encrypt(textBytes, false);字符串 outputB64 = Convert.ToBase64String(encryptedOutput);Console.WriteLine(outputB64);返回输出B64;}

Java

public static String Decrypt(String encryptedString) throws IllegalBlockSizeException, UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException{字节[] modulusBytes = Base64.decode( 2rRVVVFJRbH/wAPDtnwZwu + NXU + AZ6uXxh/SW + AMCBogg7vndZsnRiHoLttYYPqOyOhfgaBOQogrIfrKL4lipK4m52SBzw/FfcM9DsKs/rYR83tBLiIAfgdnVjF27tZID + HJMFTiI30mALjr7 + TFP + 2lIACXA1RIKTk7S9pDmX8 =");byte[] exponentBytes = Base64.decode("AQAB");BigInteger 模数 = 新 BigInteger(1,模数字节);BigInteger 指数 = new BigInteger(1, exponentBytes);RSAPrivateKeySpec rsaPrivKey = new RSAPrivateKeySpec(模数,指数);KeyFactory 事实 = KeyFactory.getInstance("RSA");PrivateKey privKey = fact.generatePrivate(rsaPrivKey);密码密码 = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.DECRYPT_MODE, privKey);byte[] base64String = Base64.decode(encodedString);byte[] plainBytes = new String(base64String).getBytes("UTF-8");byte[] cipherData = cipher.doFinal(plainBytes);System.out.println(cipherData);返回 cipherData.toString();}

解决方案

Java 解密代码的最后几行没有意义.这些行是:

byte[] base64String = Base64.decode(encodedString);byte[] plainBytes = new String(base64String).getBytes("UTF-8");byte[] cipherData = cipher.doFinal(plainBytes);System.out.println(cipherData);返回 cipherData.toString();

您必须颠倒在 .NET 中用于加密的步骤顺序.首先,您应该对编码字符串进行 Base64 解码以获取密码字节.您这样做了,但是您将结果错误地标记为 base64String.您可能应该将此结果称为 cipherData.其次,您需要解密 cipherData 以获得纯文本.第三,您应该使用带有第二个参数的 Charset 的双参数 String 构造函数从纯字节创建一个字符串.下面是代码的样子,或者接近它的样子.

byte[] cipherData = Base64.decode(encodedString);byte[] plainBytes = cipher.doFinal(cipherData);返回新字符串(plainBytes,UTF-8");

最后,在 Java 中,每个对象都有一个 toString() 方法,但它并不总是按照你的意愿去做.对于数组,toString() 方法只返回该数组的对象 id 的表示形式,类似于 JVM 中内存地址的等价物.

我错过了您在解密代码中也使用了错误的密钥.您正在使用 RSA 公钥,但您必须改用 RSA 私钥.

I am trying to encrypt strings in .NET by using a RSA algorithm and decrypt the result in Java. At the moment, I have been able to do the opposite (Encrypt in Java, Decrypt in .NET). Here I have my code that actually works (JAVA encryption):

byte[] modulusBytes = Base64.decode("2rRVVVFJRbH/wAPDtnwZwu+nxU+AZ6uXxh/sW+AMCBogg7vndZsnRiHoLttYYPqOyOhfgaBOQogrIfrKL4lipK4m52SBzw/FfcM9DsKs/rYR83tBLiIAfgdnVjF27tZID+HJMFTiI30mALjr7+tfp+2lIACXA1RIKTk7S9pDmX8=");
byte[] exponentBytes = Base64.decode("AQAB");
BigInteger modulus = new BigInteger(1, modulusBytes );
BigInteger exponent = new BigInteger(1, exponentBytes);

RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(rsaPubKey);

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);

byte[] plainBytes = new String("big kitty dancing").getBytes("UTF-8");
byte[] cipherData = cipher.doFinal( plainBytes );
String encryptedString = Base64.encode(cipherData);
return encryptedString;

And (.NET decryption)

const int PROVIDER_RSA_FULL = 1;
const string CONTAINER_NAME = "Tracker";

CspParameters cspParams;
cspParams = new CspParameters(PROVIDER_RSA_FULL);
cspParams.KeyContainerName = CONTAINER_NAME;
RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider(cspParams);
rsa1.FromXmlString("<RSAKeyValue><Modulus>2rRVVVFJRbH/wAPDtnwZwu+nxU+AZ6uXxh/sW+AMCBogg7vndZsnRiHoLttYYPqOyOhfgaBOQogrIfrKL4lipK4m52SBzw/FfcM9DsKs/rYR83tBLiIAfgdnVjF27tZID+HJMFTiI30mALjr7+tfp+2lIACXA1RIKTk7S9pDmX8=</Modulus><Exponent>AQAB</Exponent><P>+lXMCEwIN/7+eMpBrq87kQppxu3jJBTwztGTfXNaPUTx+A6uqRwug5oHBbSpYXKNDNCBzVm/0VxB3bo4FJx+ZQ==</P><Q>yasOGaJaE9xlF9T2xRuKeG9ZxCiyjhYaYB/mbtL+SIbtkRLi/AxaU4g2Il/UxhxhSXArKxIzV28zktispPJx1Q==</Q><DP>ueRgQIEFUV+fY979a1RgrVHIPpqEI1URhOMH3Q59oiXCcOumM5njyIHmWQxRAzXnG+7xlKXi1PrnRll0L4oOKQ==</DP><DQ>dfEMNgG1HJhwpxdtmqkYuoakwQvsIRzcIAuIAJh1DoWaupWJGk8/JEstHb1d+t7uJrzrAi2KyT/HscH2diE0YQ==</DQ><InverseQ>YoYF9PF6FiC0YngVeaC/eqt/ea8wMYNN3YO1LuzWpcy2exPRj2U0ZbWMvHXMUb4ea2qmhZGx1QlK4ULAuWKpXQ==</InverseQ><D>g1WAWI4pEK9TA7CA2Yyy/2FzzNiu0uQCuE2TZYRNiomo96KQXpxwqAzZLw+VDXfJMypwDMAVZe/SqzSJnFEtZxjdxaEo3VLcZ1mnbIL0vS7D6iFeYutF9kF231165qGd3k2tgymNMMpY7oYKjS11Y6JqWDU0WE5hjS2X35iG6mE=</D></RSAKeyValue>");

string data2Decrypt = "BaB21vY+RD/jiY3AAsb269fIWTEH38s0xLUfJ7CoVUgaQ6vYzB0tiJ1Ag9HNEdCcuZdGchhqnms8jpsqsHC1iKrz6QCLsgUU7VNWDfQqZYR6Rl/GwR0biK2STnOL+g06f/JUdixHOHOgROify1m8qppYo5plpOVMqYFzEMREMkM=";

byte[] encyrptedBytes = Convert.FromBase64String(data2Decrypt);

byte[] plain = rsa1.Decrypt(encyrptedBytes, false);
string decryptedString = System.Text.Encoding.UTF8.GetString(plain);
Console.WriteLine("SALIDA: " + decryptedString);

Now I want to do the opposite... But I get some errors like (the size of the key should be 128 bytes... etc) How should I do it?

Here I add the current non working code:

.NET

public string Encrypt(string text)
{
    const int PROVIDER_RSA_FULL = 1;
    const string CONTAINER_NAME = "Tracker";

    CspParameters cspParams;
    cspParams = new CspParameters(PROVIDER_RSA_FULL);
    cspParams.KeyContainerName = CONTAINER_NAME;
    RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider(cspParams);
    rsa1.FromXmlString("<RSAKeyValue><Modulus>2rRVVVFJRbH/wAPDtnwZwu+nxU+AZ6uXxh/sW+AMCBogg7vndZsnRiHoLttYYPqOyOhfgaBOQogrIfrKL4lipK4m52SBzw/FfcM9DsKs/rYR83tBLiIAfgdnVjF27tZID+HJMFTiI30mALjr7+tfp+2lIACXA1RIKTk7S9pDmX8=</Modulus><Exponent>AQAB</Exponent><P>92jJJyzFBSx6gL4Y1YpALmc5CNjoE/wETjqb3ci2v0+3rZWvJKmKy1ZEdlXpyuvXVksJ6cMdUpNAkMknUk9pTQ==</P><Q>4kxkABZOXyDLryYGCGY0b8N0FIdu5BTCFDYEdcatxl/f7ZGDS1NgHJpUWxkVXFfHy2Y/GuDOIbpcwlsO739H+w==</Q><DP>5bNFvrdUHF+VRN45VFjNCcgQLeSkY5mBrdfASoNFGA29LM5iE5nNIMfxPCS7sQiRnq6Af6YFHVtVgJchiMvtqQ==</DP><DQ>j+ng1qVY5epnXlWiFIla45C7K6sNfIMvAcdwgq39KWEjeWPGyYqWXtpOtzh2eylf6Bx4GVHKBW0NPJTIJMsfLQ==</DQ><InverseQ>8uu0dfPVDqB2qFM1Vdi8hl+2uZtN7gjT2co1cEWy29HVYBZD0k9KKCf2PbkeuSfpgFpE70wW5Hrp8V7l/SwSOw==</InverseQ><D>MM/c18zroJ2Iqi9s5/asvUBF3pjO3NSEbFjFpP/NT6WdKimvECWPz2xT6NlV0Vc6tQaAAmtn7Bt+HPhfVdrA4/ysYVe3/6TWkPjW+bvAhMWu/ZqISx11/jPYSGD9g3ZXgUiqcQM8UbOjlswoq4fpheEXTB0xdVutDLpO3qgHN6k=</D></RSAKeyValue>");

    System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    byte[] textBytes = encoding.GetBytes(text);
    byte[] encryptedOutput = rsa1.Encrypt(textBytes, false);
    string outputB64 = Convert.ToBase64String(encryptedOutput);
    Console.WriteLine(outputB64);
    return outputB64;
}

Java

public static String Decrypt(String encodedString) throws IllegalBlockSizeException, UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException
{
    byte[] modulusBytes = Base64.decode("2rRVVVFJRbH/wAPDtnwZwu+nxU+AZ6uXxh/sW+AMCBogg7vndZsnRiHoLttYYPqOyOhfgaBOQogrIfrKL4lipK4m52SBzw/FfcM9DsKs/rYR83tBLiIAfgdnVjF27tZID+HJMFTiI30mALjr7+tfp+2lIACXA1RIKTk7S9pDmX8=");
    byte[] exponentBytes = Base64.decode("AQAB");
    BigInteger modulus = new BigInteger(1, modulusBytes );
    BigInteger exponent = new BigInteger(1, exponentBytes);

    RSAPrivateKeySpec rsaPrivKey = new RSAPrivateKeySpec(modulus, exponent);
    KeyFactory fact = KeyFactory.getInstance("RSA");
    PrivateKey privKey = fact.generatePrivate(rsaPrivKey);

    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.DECRYPT_MODE, privKey);

    byte[] base64String = Base64.decode(encodedString);
    byte[] plainBytes = new String(base64String).getBytes("UTF-8");
    byte[] cipherData = cipher.doFinal(plainBytes);

    System.out.println(cipherData);
    return cipherData.toString();
}

解决方案

The last few lines of your Java decrypt code do not make sense. These lines are:

byte[] base64String = Base64.decode(encodedString);
byte[] plainBytes = new String(base64String).getBytes("UTF-8");
byte[] cipherData = cipher.doFinal(plainBytes);

System.out.println(cipherData);
return cipherData.toString();

You have to reverse the order of the steps you used to encrypt in .NET. First, you should Base64 decode the encoded string to get the cipher bytes. You did that, but you mislabeled the result as base64String. You probably should call this result cipherData. Second, you need to decrypt cipherData to get plain text. Third, you should create a string from plainbytes using the two-arg String constructor with the Charset for the second argument. Here is what the code should look like, or close to it.

byte[] cipherData = Base64.decode(encodedString);
byte[] plainBytes = cipher.doFinal(cipherData);

return new String(plainBytes, "UTF-8");

Finally, in Java every object has a toString() method but it doesn't always do what you want. For arrays the toString() method simply returns a representation of object id for that array, sort of the JVM equivalent of a memory address.

EDIT:

I missed that you are also using the wrong key in your decrypt code. Your are using the RSA public key, but you must instead use the RSA private key.

这篇关于RSA .NET 加密 Java 解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:如何从 byte[] 数组中恢复 RSA 公钥? 下一篇:如何解密从 Mifare Desfire EV1 发送的第一条消息

相关文章

最新文章