問題描述
我正在嘗試使用 RSA 算法加密 .NET 中的字符串并在 Java 中解密結(jié)果.目前,我已經(jīng)能夠做相反的事情(在 Java 中加密,在 .NET 中解密).在這里,我的代碼實(shí)際上可以工作(JAVA 加密):
<預(yù)> <代碼>字節(jié)[] modulusBytes = Base64.decode( 2rRVVVFJRbH/wAPDtnwZwu + NXU + AZ6uXxh/SW + AMCBogg7vndZsnRiHoLttYYPqOyOhfgaBOQogrIfrKL4lipK4m52SBzw/FfcM9DsKs/rYR83tBLiIAfgdnVjF27tZID + HJMFTiI30mALjr7 + TFP + 2lIACXA1RIKTk7S9pDmX8 =");byte[] exponentBytes = Base64.decode("AQAB");BigInteger 模數(shù) = 新 BigInteger(1,模數(shù)字節(jié));BigInteger 指數(shù) = new BigInteger(1, exponentBytes);RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(模數(shù),指數(shù));KeyFactory 事實(shí) = KeyFactory.getInstance("RSA");PublicKey pubKey = fact.generatePublic(rsaPubKey);密碼密碼 = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.ENCRYPT_MODE, pubKey);byte[] plainBytes = new String("大貓?zhí)?).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;/模量><指數(shù)> AQAB</指數(shù)>< 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);
現(xiàn)在我想做相反的事情......但是我遇到了一些錯(cuò)誤,比如(密鑰的大小應(yīng)該是 128 字節(jié)......等等)我應(yīng)該怎么做?
這里我添加當(dāng)前的不工作代碼:
.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;/模量><指數(shù)> AQAB</指數(shù)>< 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{字節(jié)[] modulusBytes = Base64.decode( 2rRVVVFJRbH/wAPDtnwZwu + NXU + AZ6uXxh/SW + AMCBogg7vndZsnRiHoLttYYPqOyOhfgaBOQogrIfrKL4lipK4m52SBzw/FfcM9DsKs/rYR83tBLiIAfgdnVjF27tZID + HJMFTiI30mALjr7 + TFP + 2lIACXA1RIKTk7S9pDmX8 =");byte[] exponentBytes = Base64.decode("AQAB");BigInteger 模數(shù) = 新 BigInteger(1,模數(shù)字節(jié));BigInteger 指數(shù) = new BigInteger(1, exponentBytes);RSAPrivateKeySpec rsaPrivKey = new RSAPrivateKeySpec(模數(shù),指數(shù));KeyFactory 事實(shí) = 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 中用于加密的步驟順序.首先,您應(yīng)該對(duì)編碼字符串進(jìn)行 Base64 解碼以獲取密碼字節(jié).您這樣做了,但是您將結(jié)果錯(cuò)誤地標(biāo)記為 base64String
.您可能應(yīng)該將此結(jié)果稱為 cipherData
.其次,您需要解密 cipherData 以獲得純文本.第三,您應(yīng)該使用帶有第二個(gè)參數(shù)的 Charset 的雙參數(shù) String 構(gòu)造函數(shù)從純字節(jié)創(chuàng)建一個(gè)字符串.下面是代碼的樣子,或者接近它的樣子.
byte[] cipherData = Base64.decode(encodedString);byte[] plainBytes = cipher.doFinal(cipherData);返回新字符串(plainBytes,UTF-8");
最后,在 Java 中,每個(gè)對(duì)象都有一個(gè) toString() 方法,但它并不總是按照你的意愿去做.對(duì)于數(shù)組,toString() 方法只返回該數(shù)組的對(duì)象 id 的表示形式,類似于 JVM 中內(nèi)存地址的等價(jià)物.
我錯(cuò)過了您在解密代碼中也使用了錯(cuò)誤的密鑰.您正在使用 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.
這篇關(guān)于RSA .NET 加密 Java 解密的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!