【发布时间】:2017-06-30 07:22:07
【问题描述】:
我不会为 AES 或其他加密打开此线程,因为这是我将用来加密 AES 和其他加密的密钥。我从 StackOverflow 和其他几个站点收集了几个代码并对其进行了编辑以适合我的程序,但是在尝试使用 RSA 进行逐块加密时,我只能加密大小为 1 KB 的小文本文件。文本文件的加密和解密工作正常。但是,加密图片和大于 1 KB 的任何文件都会产生空白 加密文件。
如果有人可以帮助我指出这段代码导致文件大于 1 KB 导致空白输出文件/加密文件的位置,我想寻求帮助。这段代码适用于 AES,但我不确定为什么它不适用于 RSA 加密。问题从Encrypt_File 开始在它读取它的循环周围的某个地方。
代码:
public static final String ALGORITHM = "RSA";
private static final short KEY_LENGTH = 1024;
private static final short KEY_BYTES = 32;
private static final String CIPHER_EXTENSION = ".cgfile";
public void Encrypt_File(Path path_fileToEncrypt) {
//get file name and the new file name
String fileName = path_fileToEncrypt.getFileName().toString();
String encryptedFileName = fileName+CIPHER_EXTENSION;
String pathToEncryptedFile = path_fileToEncrypt.getParent()+File.separator+encryptedFileName;
//attempt to open the public key
try (ObjectInputStream publicKeyFile = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE))) {
//load the key
PublicKey publicKey = (PublicKey) publicKeyFile.readObject();
// load file to encrypt and inputstream
FileInputStream fileInputStream = new FileInputStream(new File(path_fileToEncrypt.toString()));
// init the cipher
final Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
CipherOutputStream cos = new CipherOutputStream(new FileOutputStream(pathToEncryptedFile),cipher);
byte[] buffer = new byte[KEY_BYTES];
int count;
while((count = fileInputStream.read(buffer))>0){
cos.write(buffer, 0, count);
}
//close
fileInputStream.close();
cos.close();
//delete fileToEncrypt since we have the encrypted file now
DeleteFile(new File(path_fileToEncrypt.toString()));
System.out.println("Finished encrypting "+ fileName +" It's new file name is "+ encryptedFileName);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
CGcipher rsaencrypt = new CGcipher();
Path pathTosecret = Paths.get(System.getProperty("user.dir"), "pic.png");
// Encrypt the string using the public key
rsaencrypt.Encrypt_File(pathTosecret);
//rsaencrypt.Decrypt_File(pathTosecret);
} catch (Exception e) {
System.out.println(e.toString());
}
}
【问题讨论】:
-
@LukePark 好吧,它仍然可以保护机密性。完整性和当然真实性不会受到保护,但 AES/CBC 也不是这种情况。当然,这在空间和 CPU 时间上都是低效的,防止定时攻击可能是一个问题。但最糟糕的 5 件事是什么?不。
-
请注意,代码格式(标识符大小写,在运算符前后不使用空格),尤其是异常处理让我有点畏缩。您可能想研究一下(您是否知道可以在 try-with-resources 中放置多个语句,并且您可以在 try-with-resources 之前初始化密码?我还将分开读取公钥并使用
getEncoded和密钥工厂而不是对象序列化。 -
@MaartenBodewes 我确实使用了多个 try-with-resources 但不在本节中,因为我仍在尝试找出导致问题的原因,是的,代码看起来很糟糕。关于运算符之前/之后的空间,我会注意到这一点。显然,我习惯用 C++ 做所有的空格。对于异常处理,我把它做成了一个简单的 catch 块,这样我就知道这部分代码中发生了什么,虽然我知道我可以让它独立,但现在我只想让它工作,然后让它看起来更好。这更多的是个人喜好,但我会再次注意到这一点
-
@MaartenBodewes 只是为了清除一些东西。通过将公钥和
getEncoded和密钥工厂分开,您的意思是制作一个单独的函数来处理它们吗? -
是的,我就是这个意思。如果您使用
getEncoded()存储密钥,它将被存储为二进制SubjectPublicKeyInfo结构,该结构应该与许多软件兼容(当然除了Mickeysoft,让他们使用专有结构代替)。
标签: java file encryption cryptography output