加密文件在唯一文件中附加包装密钥
Encrypt a file appending wrapped key in unique file
我正在尝试使用封装在 RSA 密钥对中的 AES 密钥来加密文件。
我试图将包装密钥放在文件的开头,然后为了解密我使用包装密钥的前 256 个字节来获取它。
问题是我正在以 1024 字节为单位加密文件。因此,为了解密,我需要获取文件的最后一个字节(不是前 256 个字节,因为它们是密钥)
所以在this image你可以看到过程
<a href='http://postimg.org/image/htmelww63/' target='_blank'><img src='http://s1.postimg.org/htmelww63/Blank_Flowchart_New_Page.jpg' border='0' alt="Blank Flowchart New Page" /></a>
所以问题是当我需要解密除前 256 个字节之外的文件时。我找不到有效的算法...
这里是加密代码:
public static void fileEncripWrapped(File in, File out, PublicKey pub, byte [] key) {
try {
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
//Encrypting wrapped key
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.WRAP_MODE, pub);
byte[] encKey = cipher.wrap(keySpec);
FileOutputStream osAppend = new FileOutputStream(out);
osAppend.write(encKey);
osAppend.close();
// Crypting the file
cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
FileInputStream is = new FileInputStream(in);
CipherOutputStream os = new CipherOutputStream(new FileOutputStream(out, true), cipher);
copy(is, os);
is.close();
os.close();
} catch (Exception ex) {
System.err.println("Ha succeït un error xifrant: " + ex);
}
}
这是我用于以 1024 字节为单位将 inputStream 复制到 outputStream 的代码。
private static void copy(InputStream is, OutputStream os) throws IOException {
int i;
byte[] b = new byte[1024];
while((i=is.read(b))!=-1) {
os.write(b, 0, i);
}
}
现在的问题是解密:
public static void fileUncryptWrapped(File in, File out, PrivateKey priv) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.UNWRAP_MODE, priv);
//First we must to take the wrapped key in the first 256 bytes of the file:
byte[] bufferKey = new byte[256];
InputStream is = new FileInputStream(in);
if (is.read(bufferKey) != bufferKey.length) {
}
is.close();
Key ky = cipher.unwrap(bufferKey, "AES", Cipher.SECRET_KEY);¡
// Now we must to uncrypt the rest of the file
cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, ky);
CipherInputStream ix = new CipherInputStream(new FileInputStream(in), cipher);
FileOutputStream os = new FileOutputStream(out);
copy(ix, os);
ix.close();
os.close();
} catch (Exception ex) {
System.err.println("Ha succeït un error xifrant: " + ex);
}
}
copy函数取前256后的字节需要做哪些修改?我尝试过类似的方法,但它不起作用...
// Get the size of the file
long streamLength = inputStream.available();
if (streamLength > Integer.MAX_VALUE) {
// File is too large
}
// Create the byte array to hold the data
byte[] bytes = new byte[1024];
// Read in the bytes
int block_size = 1024;
int offset = 256;
int numRead = 0;
while (offset < (int) streamLength && (numRead = inputStream.read(bytes, offset, block_size)) >= 0) {
offset += numRead;
outputStream.write(bytes, 0 , block_size );
}
你的解密代码应该是这样的:
public static void fileDecryptWrapped(File in, File out, PrivateKey priv)
throws GeneralSecurityException, IOException {
Signature signature = Signature.getInstance("SHA1WITHRSA");
signature.initSign(priv);
signature.update("test".getBytes());
byte[] bufferKey = signature.sign();
// First we must to take the wrapped key in the first bufferKey.length bytes of the file
InputStream is = new FileInputStream(in);
if (is.read(bufferKey) != bufferKey.length) {
is.close();
throw new IllegalStateException("Too short file");
}
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.UNWRAP_MODE, priv);
Key aesKey = cipher.unwrap(bufferKey, "AES", Cipher.SECRET_KEY);
// Now we must to decrypt the rest of the file
cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, aesKey);
CipherInputStream ix = new CipherInputStream(is, cipher);
FileOutputStream os = new FileOutputStream(out);
copy(ix, os);
ix.close();
os.close();
}
请注意,读取密钥后相同的 FileInputStream
将未经修改传递给 CipherInputStream
。
我在你的方法中看到的问题是,加密文件中没有结构。例如,使用非 2K RSA 密钥将严重失败,因为解密算法总是需要 256 字节的包装密钥。
我正在尝试使用封装在 RSA 密钥对中的 AES 密钥来加密文件。
我试图将包装密钥放在文件的开头,然后为了解密我使用包装密钥的前 256 个字节来获取它。
问题是我正在以 1024 字节为单位加密文件。因此,为了解密,我需要获取文件的最后一个字节(不是前 256 个字节,因为它们是密钥)
所以在this image你可以看到过程
<a href='http://postimg.org/image/htmelww63/' target='_blank'><img src='http://s1.postimg.org/htmelww63/Blank_Flowchart_New_Page.jpg' border='0' alt="Blank Flowchart New Page" /></a>
所以问题是当我需要解密除前 256 个字节之外的文件时。我找不到有效的算法...
这里是加密代码:
public static void fileEncripWrapped(File in, File out, PublicKey pub, byte [] key) {
try {
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
//Encrypting wrapped key
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.WRAP_MODE, pub);
byte[] encKey = cipher.wrap(keySpec);
FileOutputStream osAppend = new FileOutputStream(out);
osAppend.write(encKey);
osAppend.close();
// Crypting the file
cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
FileInputStream is = new FileInputStream(in);
CipherOutputStream os = new CipherOutputStream(new FileOutputStream(out, true), cipher);
copy(is, os);
is.close();
os.close();
} catch (Exception ex) {
System.err.println("Ha succeït un error xifrant: " + ex);
}
}
这是我用于以 1024 字节为单位将 inputStream 复制到 outputStream 的代码。
private static void copy(InputStream is, OutputStream os) throws IOException {
int i;
byte[] b = new byte[1024];
while((i=is.read(b))!=-1) {
os.write(b, 0, i);
}
}
现在的问题是解密:
public static void fileUncryptWrapped(File in, File out, PrivateKey priv) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.UNWRAP_MODE, priv);
//First we must to take the wrapped key in the first 256 bytes of the file:
byte[] bufferKey = new byte[256];
InputStream is = new FileInputStream(in);
if (is.read(bufferKey) != bufferKey.length) {
}
is.close();
Key ky = cipher.unwrap(bufferKey, "AES", Cipher.SECRET_KEY);¡
// Now we must to uncrypt the rest of the file
cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, ky);
CipherInputStream ix = new CipherInputStream(new FileInputStream(in), cipher);
FileOutputStream os = new FileOutputStream(out);
copy(ix, os);
ix.close();
os.close();
} catch (Exception ex) {
System.err.println("Ha succeït un error xifrant: " + ex);
}
}
copy函数取前256后的字节需要做哪些修改?我尝试过类似的方法,但它不起作用...
// Get the size of the file
long streamLength = inputStream.available();
if (streamLength > Integer.MAX_VALUE) {
// File is too large
}
// Create the byte array to hold the data
byte[] bytes = new byte[1024];
// Read in the bytes
int block_size = 1024;
int offset = 256;
int numRead = 0;
while (offset < (int) streamLength && (numRead = inputStream.read(bytes, offset, block_size)) >= 0) {
offset += numRead;
outputStream.write(bytes, 0 , block_size );
}
你的解密代码应该是这样的:
public static void fileDecryptWrapped(File in, File out, PrivateKey priv)
throws GeneralSecurityException, IOException {
Signature signature = Signature.getInstance("SHA1WITHRSA");
signature.initSign(priv);
signature.update("test".getBytes());
byte[] bufferKey = signature.sign();
// First we must to take the wrapped key in the first bufferKey.length bytes of the file
InputStream is = new FileInputStream(in);
if (is.read(bufferKey) != bufferKey.length) {
is.close();
throw new IllegalStateException("Too short file");
}
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.UNWRAP_MODE, priv);
Key aesKey = cipher.unwrap(bufferKey, "AES", Cipher.SECRET_KEY);
// Now we must to decrypt the rest of the file
cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, aesKey);
CipherInputStream ix = new CipherInputStream(is, cipher);
FileOutputStream os = new FileOutputStream(out);
copy(ix, os);
ix.close();
os.close();
}
请注意,读取密钥后相同的 FileInputStream
将未经修改传递给 CipherInputStream
。
我在你的方法中看到的问题是,加密文件中没有结构。例如,使用非 2K RSA 密钥将严重失败,因为解密算法总是需要 256 字节的包装密钥。