我遇到过一些加密问题,但是看不清楚我做错了什么。我正在尝试使用Android上的RSA加密AESkey并使用C#解密服务器端,但不断收到“错误数据”异常。
我使用Base64encoding将加密密钥从客户端移动到服务器,并注意到在使用JSON POST请求从客户端(Android App)移动密钥后,密钥中有许多“\ u000a”使加密数据长度941导致“数据大到解密”被删除时将长度调到920,这允许80个8字节的迭代,并让我到现在的Bad Data问题。
我已检查密钥长度和算法是否正确,并且都设置为2048位密钥并使用PKCS1Padding。
“错误数据”例外 在以下方案中将抛出此异常。
a)用于解密的RSA私钥与用于加密的RSA公钥不匹配。
b)传入Decrypt()方法的二进制数据不正确。如果应用程序代码假设加密数据的长度或传入的数据与Encrypt()方法返回的确切字节不匹配,则可能发生这种情况。
我通过GET从服务器上获取公钥,然后返回RSACryptoServiceProvider.ToXMLString(false);并为私钥使用相同的密钥库,因此无法将其视为1。
据我所知,c#decrypter不对加密数据的大小做任何假设。可能我的设置块大小为8但是在我知道加密的AESkey的大小之后。
我一直在寻找解决方案而找不到解决方案,所以如果有任何帮助,我将不胜感激。抱歉,如果我是愚蠢的,并且错过了一些简单的事情,但是如果我是的话,我会看到我的眼罩,并且无法看到它。
Java加密
private byte[] encryptRSA(byte [] data) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
//instance of singleton PublicKey
AppPublicKey currKey = AppPublicKey.getInstance();
Log.d("ENCRYPT.MOD: ", currKey.getModBytes().toString());
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(new BigInteger(1,currKey.getModBytes()), new BigInteger(1,currKey.getExpBytes()));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherData = cipher.doFinal(data);
Log.d("RSAENCRYPTION: ",Base64.encodeToString(cipherData, 1));
return cipherData;
}
C#Decrypt
public string DecryptString(string inputString, int dwKeySize)
{
// TODO: Add Proper Exception Handlers
CspParameters cp = new CspParameters();
cp.KeyContainerName = "real_Keystore";
RSACryptoServiceProvider rsaCryptoServiceProvider
= new RSACryptoServiceProvider(dwKeySize,cp);
int base64BlockSize = 8;
int iterations = inputString.Length / base64BlockSize;
ArrayList arrayList = new ArrayList();
for (int i = 0; i < iterations; i++)
{
byte[] encryptedBytes = Convert.FromBase64String(
inputString.Substring(base64BlockSize * i, base64BlockSize));
//Array.Reverse(encryptedBytes);
arrayList.AddRange(rsaCryptoServiceProvider.Decrypt(
encryptedBytes, false));
}
return Encoding.UTF32.GetString(arrayList.ToArray(
Type.GetType("System.Byte")) as byte[]);
}
答案 0 :(得分:0)
无法一次向RSA操作提供几个字节。
此外,代码似乎不太可能执行适当数量的base 64迭代(如您在android中为base 64定义NO_PADDING
,使用1
而不是常量)。通常,RSA加密的输出不会是3个字节的倍数,因此至少有一个块不在标记范围内。
您可能需要仔细查看正在使用的API函数,并花些时间研究.NET上的RSA示例。通常,RSA仅用于加密少量数据(例如对称数据加密密钥),因此您应该能够一次解码所有base64数据。
请在调试器中测试输入和输出。加密/解密问题通常需要比较加密/解密算法的确切输入和输出。