当邮件太长时,我遇到RSA加密问题。
MyCipher:
public static byte[] encrypt(byte[] dataToEncrypt, PublicKey pubk){
try{
System.out.println("in encrypt");
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubk);
byte[] encrypted = new byte[dataToEncrypt.length];
System.out.println("Imagebyte length: " + dataToEncrypt.length);
byte[] temp = new byte[53];
byte[] temp2 = null;
int x, y, z = 0;
int repeats = dataToEncrypt.length / 53;
System.out.println("Iterations: " + repeats);
for (z = 0; z < repeats; z++) {
System.out.println("Iteration number: " + z);
int offset = z * 53;
for (x = 0; x < 53; x++) {
temp[x] = (byte) dataToEncrypt[offset + x];
}
temp2 = cipher.doFinal(temp);
for (y = 0; y < 53; y++) {
encrypted[offset + y] = (byte) temp2[y];
}
temp2 = null;
}
return encrypted;
}catch(Exception e){
return null;
}
}
public static byte[] decrypt(byte[] bytesIn, PrivateKey prvk){
try {
System.out.println("in decrypt");
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
System.out.println("read out" + prvk);
cipher.init(Cipher.DECRYPT_MODE, prvk);
byte[] decrypted = new byte[bytesIn.length];
System.out.println("Imagebyte length: " + bytesIn.length);
byte[] temp = new byte[53];
byte[] temp2 = null;
int x, y, z = 0;
int repeats = bytesIn.length / 53;
System.out.println("Iterations: " + repeats);
for (z = 0; z < repeats; z++) {
System.out.println("Iteration number: " + z);
int offset = z * 53;
for (x = 0; x < 53; x++) {
temp[x] = (byte) bytesIn[offset + x];
}
temp2 = cipher.doFinal(temp);
for (y = 0; y < 53; y++) {
decrypted[offset + y] = (byte) temp2[y];
}
temp2 = null;
}
return decrypted;
} catch (Exception e) {
System.err.println(e);
return null;
}
}
主要
public static void main(String args[]) {
MsgAtoB_1 msg= new MsgAtoB_1(new BigInteger(String.valueOf(System.currentTimeMillis())), "login");
byte [] tab = MySerializer.serialize(msg);
KeyPair key = Keys.generateKeyPair();
byte [] crypt = MyCipher.encrypt(tab, key.getPublic());
byte [] decrypt = MyCipher.decrypt(crypt,key.getPrivate() );
if(tab.equals(decrypt)) System.out.println("yes it's work ");
else System.out.println("KOOOOOOOOOOO");
}
输出:
run:
in encrypt
Imagebyte length: 319
Iterations: 6
Iteration number: 0
Iteration number: 1
Iteration number: 2
Iteration number: 3
Iteration number: 4
Iteration number: 5
in decrypt
read outsun.security.rsa.RSAPrivateCrtKeyImpl@fff5bef2
Imagebyte length: 319
Iterations: 6
Iteration number: 0
javax.crypto.BadPaddingException: Data must start with zero
KOOOOOOOOOOO
答案 0 :(得分:0)
您指定了填充模式,这意味着密码填充输入数据并返回不同(更大)长度的数组。
特别是,两个方法中的以下行都接收来自密码的数据,但不以任何方式使用返回数据的长度:
temp2 = cipher.doFinal(temp);
加密时,基本上将每个“块”截断为53个字节(如何以及如何选择该数字是另一个问题)。解密时,您将此截断的数据传递给密码,该密码可预测导致BadPaddingException
。
可以通过在某种调整大小数组(例如ByteArrayOutputStream
)中收集单个加密块来“修复”您的代码,并存储每个块的长度,以便在解码时能够拆分流,但是你会以糟糕的“流式”密码结束。
您应该考虑使用另一种密码(例如AES)和另一种密码模式(例如CTR)来提供开箱即用的流媒体功能。
答案 1 :(得分:0)
解决方案就在这里:使用Java和RSA加密和解密大数据 Encrypting and decrypting large data using Java and RSA