从其他客户端解密 RSA 时出现 BadPaddingException
BadPaddingException while decrypting RSA from other client
我正在编写一个 Android 应用程序,将其 RSA public 密钥广播到网络,并允许其他客户端通过 TCP 连接到它。我有自己的自定义协议和数据包结构,然后我将其加密并发送给客户端(数据包 -> AES -> RSA with client's public key -> client)。
private String encryptPacket(String packet, String pubKey)
{
PublicKey clientPub = KeyFunctions.stringToKey(pubKey);
String aesEncryptedData = null;
byte[] rsaEncryptedData = null;
String temp = null;
try
{
// AES
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
final SecretKeySpec secretKey = new SecretKeySpec(Constants.KEY.getBytes(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
aesEncryptedData = Base64.encodeToString(cipher.doFinal(packet.getBytes()), Base64.NO_PADDING|Base64.NO_WRAP); //base64 the aes
// RSA
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(Cipher.ENCRYPT_MODE, clientPub);
rsaEncryptedData = c.doFinal(aesEncryptedData.getBytes());
temp = Base64.encodeToString(rsaEncryptedData, Base64.NO_PADDING|Base64.NO_WRAP); // base 64 the rsa
Log.d("ENC SEND", temp);
} catch (Exception e)
{
e.printStackTrace();
}
return temp;
}
public String decryptPacket(String encryptedData, Context context)
{
// get the keys
PrivateKey pri = KeyFunctions.getPrivateKey(context);
byte[] packet = null;
byte[] decrypted = null;
String temp = null;
try
{
//RSA
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(Cipher.DECRYPT_MODE, pri);
byte[] rsaTempArray = Base64.decode(encryptedData, Base64.NO_PADDING|Base64.NO_WRAP);
packet = c.doFinal(rsaTempArray);
// AES
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
final SecretKeySpec secretKey = new SecretKeySpec(Constants.KEY.getBytes(), "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
final String decryptedString = new String(cipher.doFinal(Base64.decode(packet, Base64.NO_PADDING|Base64.NO_WRAP)));
temp = decryptedString;
} catch (Exception e)
{
e.printStackTrace();
}
Log.d("ENC REC", temp);
return temp;
}
当客户端向自己发送数据时,此代码有效。但是,将它发送给另一个客户端时它不起作用,给我以下错误:javax.crypto.BadPaddingException: error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02
这个异常是在 decryptPacket 调用时引发的,packet = c.doFinal(rsaTempArray);
我试图通过调试验证 public 键的值是否正确,似乎没有任何问题。
更新
这是更新后的代码
private byte[] encryptPacket(Packet packet, String pubKey)
{
PublicKey clientPub = KeyFunctions.stringToKey(pubKey);
byte[] aesEncryptedData = null;
byte[] rsaEncryptedData = null;
byte[] temp = null;
Log.d("START", "==========ENCRYPT==========");
try
{
// AES
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
final SecretKeySpec secretKey = new SecretKeySpec(Constants.KEY.getBytes(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte aesTempArray[] = cipher.doFinal(packet.getBytes());
Log.d("ENC AES TEMP", new String(aesTempArray, "UTF-8"));
aesEncryptedData = Base64.encode(aesTempArray, Base64.NO_PADDING | Base64.NO_WRAP); //base64 the aes
Log.d("ENC AES ENCR", new String(aesEncryptedData, "UTF-8"));
// RSA
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(Cipher.ENCRYPT_MODE, clientPub);
rsaEncryptedData = c.doFinal(aesEncryptedData);
Log.d("ENC RSA ENCR", new String(rsaEncryptedData, "UTF-8"));
temp = Base64.encode(rsaEncryptedData, Base64.NO_PADDING | Base64.NO_WRAP); // base 64 the rsa
Log.d("ENC RSA TEMP", new String(temp, "UTF-8"));
} catch (Exception e)
{
e.printStackTrace();
}
return temp;
}
public Packet decryptPacket(byte[] encryptedData, Context context)
{
// get the keys
PrivateKey pri = KeyFunctions.getPrivateKey(context);
Packet p = null;
byte[] aesDecryptedData = null;
byte[] rsaDecryptedData = null;
Log.d("START", "==========DECRYPT==========");
try
{
//RSA
Log.d("DEC INIT", new String(encryptedData, "UTF-8"));
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(Cipher.DECRYPT_MODE, pri);
byte[] rsaTempArray = Base64.decode(encryptedData, Base64.NO_PADDING | Base64.NO_WRAP);
Log.d("DEC RSA TEMP", new String(rsaTempArray, "UTF-8"));
rsaDecryptedData = c.doFinal(rsaTempArray);
Log.d("DEC RSA ENCR", new String(rsaDecryptedData, "UTF-8"));
// AES
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
final SecretKeySpec secretKey = new SecretKeySpec(Constants.KEY.getBytes(), "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] aesTempArray = Base64.decode(rsaDecryptedData, Base64.NO_PADDING | Base64.NO_WRAP);
Log.d("DEC AES TEMP", new String(aesTempArray, "UTF-8"));
aesDecryptedData = cipher.doFinal(aesTempArray);
Log.d("DEC AES DEC", new String(aesDecryptedData, "UTF-8"));
p = new Packet(aesDecryptedData);
} catch (Exception e)
{
e.printStackTrace();
}
return p;
}
代码不再使用任何字符串,但仍然出现相同的异常。我现在已经确定接收方已收到与客户端发送的完全相同的数据。当客户端将数据发送到同一设备上的服务器时,该程序可以完美运行,但是当我尝试发送到另一台设备服务器时出现上述异常。两个设备都有自己的私钥/ public 密钥对。每个设备都有彼此的 public 密钥。
Encryption/Decryption 代码很好,我使用错误的 IP 地址来找出 public 密钥。感谢您的帮助!
我正在编写一个 Android 应用程序,将其 RSA public 密钥广播到网络,并允许其他客户端通过 TCP 连接到它。我有自己的自定义协议和数据包结构,然后我将其加密并发送给客户端(数据包 -> AES -> RSA with client's public key -> client)。
private String encryptPacket(String packet, String pubKey)
{
PublicKey clientPub = KeyFunctions.stringToKey(pubKey);
String aesEncryptedData = null;
byte[] rsaEncryptedData = null;
String temp = null;
try
{
// AES
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
final SecretKeySpec secretKey = new SecretKeySpec(Constants.KEY.getBytes(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
aesEncryptedData = Base64.encodeToString(cipher.doFinal(packet.getBytes()), Base64.NO_PADDING|Base64.NO_WRAP); //base64 the aes
// RSA
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(Cipher.ENCRYPT_MODE, clientPub);
rsaEncryptedData = c.doFinal(aesEncryptedData.getBytes());
temp = Base64.encodeToString(rsaEncryptedData, Base64.NO_PADDING|Base64.NO_WRAP); // base 64 the rsa
Log.d("ENC SEND", temp);
} catch (Exception e)
{
e.printStackTrace();
}
return temp;
}
public String decryptPacket(String encryptedData, Context context)
{
// get the keys
PrivateKey pri = KeyFunctions.getPrivateKey(context);
byte[] packet = null;
byte[] decrypted = null;
String temp = null;
try
{
//RSA
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(Cipher.DECRYPT_MODE, pri);
byte[] rsaTempArray = Base64.decode(encryptedData, Base64.NO_PADDING|Base64.NO_WRAP);
packet = c.doFinal(rsaTempArray);
// AES
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
final SecretKeySpec secretKey = new SecretKeySpec(Constants.KEY.getBytes(), "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
final String decryptedString = new String(cipher.doFinal(Base64.decode(packet, Base64.NO_PADDING|Base64.NO_WRAP)));
temp = decryptedString;
} catch (Exception e)
{
e.printStackTrace();
}
Log.d("ENC REC", temp);
return temp;
}
当客户端向自己发送数据时,此代码有效。但是,将它发送给另一个客户端时它不起作用,给我以下错误:javax.crypto.BadPaddingException: error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02
这个异常是在 decryptPacket 调用时引发的,packet = c.doFinal(rsaTempArray);
我试图通过调试验证 public 键的值是否正确,似乎没有任何问题。
更新
这是更新后的代码
private byte[] encryptPacket(Packet packet, String pubKey)
{
PublicKey clientPub = KeyFunctions.stringToKey(pubKey);
byte[] aesEncryptedData = null;
byte[] rsaEncryptedData = null;
byte[] temp = null;
Log.d("START", "==========ENCRYPT==========");
try
{
// AES
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
final SecretKeySpec secretKey = new SecretKeySpec(Constants.KEY.getBytes(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte aesTempArray[] = cipher.doFinal(packet.getBytes());
Log.d("ENC AES TEMP", new String(aesTempArray, "UTF-8"));
aesEncryptedData = Base64.encode(aesTempArray, Base64.NO_PADDING | Base64.NO_WRAP); //base64 the aes
Log.d("ENC AES ENCR", new String(aesEncryptedData, "UTF-8"));
// RSA
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(Cipher.ENCRYPT_MODE, clientPub);
rsaEncryptedData = c.doFinal(aesEncryptedData);
Log.d("ENC RSA ENCR", new String(rsaEncryptedData, "UTF-8"));
temp = Base64.encode(rsaEncryptedData, Base64.NO_PADDING | Base64.NO_WRAP); // base 64 the rsa
Log.d("ENC RSA TEMP", new String(temp, "UTF-8"));
} catch (Exception e)
{
e.printStackTrace();
}
return temp;
}
public Packet decryptPacket(byte[] encryptedData, Context context)
{
// get the keys
PrivateKey pri = KeyFunctions.getPrivateKey(context);
Packet p = null;
byte[] aesDecryptedData = null;
byte[] rsaDecryptedData = null;
Log.d("START", "==========DECRYPT==========");
try
{
//RSA
Log.d("DEC INIT", new String(encryptedData, "UTF-8"));
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(Cipher.DECRYPT_MODE, pri);
byte[] rsaTempArray = Base64.decode(encryptedData, Base64.NO_PADDING | Base64.NO_WRAP);
Log.d("DEC RSA TEMP", new String(rsaTempArray, "UTF-8"));
rsaDecryptedData = c.doFinal(rsaTempArray);
Log.d("DEC RSA ENCR", new String(rsaDecryptedData, "UTF-8"));
// AES
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
final SecretKeySpec secretKey = new SecretKeySpec(Constants.KEY.getBytes(), "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] aesTempArray = Base64.decode(rsaDecryptedData, Base64.NO_PADDING | Base64.NO_WRAP);
Log.d("DEC AES TEMP", new String(aesTempArray, "UTF-8"));
aesDecryptedData = cipher.doFinal(aesTempArray);
Log.d("DEC AES DEC", new String(aesDecryptedData, "UTF-8"));
p = new Packet(aesDecryptedData);
} catch (Exception e)
{
e.printStackTrace();
}
return p;
}
代码不再使用任何字符串,但仍然出现相同的异常。我现在已经确定接收方已收到与客户端发送的完全相同的数据。当客户端将数据发送到同一设备上的服务器时,该程序可以完美运行,但是当我尝试发送到另一台设备服务器时出现上述异常。两个设备都有自己的私钥/ public 密钥对。每个设备都有彼此的 public 密钥。
Encryption/Decryption 代码很好,我使用错误的 IP 地址来找出 public 密钥。感谢您的帮助!