我想多次加密一个字符串。但是我不知道为什么我以一个空字节数组结尾。一个公钥是可以的,但是添加另一个则返回空结果。有人知道为什么吗?
private static byte[] encrypt(LinkedList<PublicKey> keys, byte[] input) throws Exception {
System.out.println("Input length : " + input.length);
if (keys.isEmpty()) {
return input;
}
PublicKey publicKey = keys.poll();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
try (CipherOutputStream cipherOutputStream = new CipherOutputStream(byteArrayOutputStream, cipher)) {
cipherOutputStream.write(input);
}
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
return encrypt(keys, byteArrayOutputStream.toByteArray());
}
public static void main(String[] args) throws Exception {
KeyPair pair1 = createPair();
KeyPair pair2 = createPair();
LinkedList<PublicKey> keys = new LinkedList<>();
keys.add(pair1.getPublic());
keys.add(pair2.getPublic());
byte[] result = encrypt(keys, "Just testing".getBytes(Charset.forName("UTF-8")));
System.out.println(new String(result, Charset.forName("UTF-8")));
}
public static KeyPair createPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048);
return keyPairGen.generateKeyPair();
}
Run Code Online (Sandbox Code Playgroud)
输出是
Input length : 12
Input length : 256
Input length : 0
Run Code Online (Sandbox Code Playgroud)
在Topaco的回答之后。.一个有效的版本是:
private static BufferedInputStream encryptS(LinkedList<PublicKey> keys, BufferedInputStream inputStream) throws Exception {
if (keys.isEmpty()) {
return inputStream;
}
PublicKey publicKey = keys.poll();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int currentPos = 0;
while (inputStream.available() > 0) {
int sizeToRead = Math.min(inputStream.available(), 245);
try (CipherOutputStream cipherOutputStream = new CipherOutputStream(byteArrayOutputStream, cipher)) {
byte[] array = new byte[sizeToRead];
inputStream.read(array, 0, sizeToRead);
cipherOutputStream.write(array);
currentPos += sizeToRead;
}
}
byteArrayOutputStream.close();
return encryptS(keys, new BufferedInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())));
}
Run Code Online (Sandbox Code Playgroud)
对于RSA,必须考虑以下因素:
0],[ 1],[ 2],[ 3]。填充表示根据特定方案[ 4]将其他字节添加到消息中。5]。这意味着在第一次加密后已经达到最大允许长度。因此,在没有填充的情况下,不超过最大长度,而在填充的情况下,则超过了最大长度。
使用创建密码实例
Cipher.getInstance("RSA")
Run Code Online (Sandbox Code Playgroud)
对应于
Cipher.getInstance("RSA/ECB/PKCS1Padding")
Run Code Online (Sandbox Code Playgroud)
对于SunJCE-Provider([ 6],[ 7]),即PKCS1 v1.5填充使用至少11个字符的填充,以便密钥大小为256字节时,消息的最大大小不得超过245字节。
这就是为什么当前代码中的递归加密不起作用的原因。如果密码实例是通过以下方式创建的
Cipher.getInstance("RSA/ECB/NoPadding")
Run Code Online (Sandbox Code Playgroud)
(不使用填充),当前代码有效。
但是,出于安全原因,实际上必须始终使用填充!
| 归档时间: |
|
| 查看次数: |
57 次 |
| 最近记录: |