Java 使用CipherOutputStream的递归加密提供一个空字节[]
我想对字符串加密多次。但我不知道为什么我会以一个空字节数组结束。 一个公钥可以,但添加另一个公钥将返回空结果。。有人知道为什么吗Java 使用CipherOutputStream的递归加密提供一个空字节[],java,encryption,Java,Encryption,我想对字符串加密多次。但我不知道为什么我会以一个空字节数组结束。 一个公钥可以,但添加另一个公钥将返回空结果。。有人知道为什么吗 private static byte[] encrypt(LinkedList<PublicKey> keys, byte[] input) throws Exception { System.out.println("Input length : " + input.length); if (keys.isEmpty()) {
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();
}
在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())));
}
私有静态BufferedInputStream加密(LinkedList密钥,BufferedInputStream inputStream)引发异常{
if(key.isEmpty()){
返回输入流;
}
PublicKey PublicKey=keys.poll();
ByteArrayOutputStream ByteArrayOutputStream=新建ByteArrayOutputStream();
Cipher Cipher=Cipher.getInstance(“RSA/ECB/PKCS1Padding”);
cipher.init(cipher.ENCRYPT_模式,公钥);
int currentPos=0;
while(inputStream.available()>0){
int sizeToRead=Math.min(inputStream.available(),245);
try(CipherOutputStream CipherOutputStream=new CipherOutputStream(byteArrayOutputStream,cipher)){
字节[]数组=新字节[sizeToRead];
读取(数组,0,sizeToRead);
cipherOutputStream.write(数组);
currentPos+=sizeToRead;
}
}
byteArrayOutputStream.close();
返回加密(密钥,新的BufferedInputStream(新的ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
}
对于RSA,必须考虑以下因素:
- 消息加上填充的长度不得超过键长度(=模数的大小)。填充意味着根据特定的方案向消息中添加额外的字节
- 密文的长度对应于密钥长度(=模数的大小)
Cipher.getInstance("RSA")
对应于
Cipher.getInstance("RSA/ECB/PKCS1Padding")
对于SunJCE提供程序(,),即PKCS1 v1.5 padding与至少11个字符的padding一起使用,因此,密钥大小为256字节时,消息的最大大小不得超过245字节
这就是为什么当前代码中的递归加密不起作用的原因。如果密码实例是使用
Cipher.getInstance("RSA/ECB/NoPadding")
(未使用填充),当前代码有效
然而,出于安全原因,在实践中必须始终使用填充 关闭密码输出流后关闭字节数组输出流是冗余的,关闭前也是冗余的。不能使用RSA加密任意长度的数据。使用a加密任意长度的数据并保留异步加密的语义。@user207421,特别是因为flush和close都是noop。@BoristeSpider在使用
ByteArrayOutputStream
时没有操作,但我写的总是正确的。
Cipher.getInstance("RSA/ECB/NoPadding")