gpt4 book ai didi

JAVA 将 AES key 、初始化 vector 和数据从加密文件中分离出来,并在加密过程中使用这 3 种组合

转载 作者:行者123 更新时间:2023-12-02 09:59:56 26 4
gpt4 key购买 nike

我已经创建了结合 AES 加密、intilizatio vector 和原始数据的加密文件。所以我的加密文件包含以上 3 个加密形式的元素。现在,在解密过程中,我再次陷入分离所有这 3 个元素的困境,此外,我必须使用在加密过程中生成的解密过程中硬编码的 AES key 长度。

public static void encrypt() throws Exception {

// RSA with ECB mode
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, generatePublicKey(readKeysFromFile("My_public.pub")));

// AES key generator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, srandom);
SecretKey skey = kgen.generateKey();

// Initialization vector 16 byte
byte[] iv = new byte[128/8];
srandom.nextBytes(iv);
IvParameterSpec ivspec = new IvParameterSpec(iv);

try (FileOutputStream out = new FileOutputStream("dataFile" + ".enc")) {
{
byte[] b = cipher.doFinal(skey.getEncoded());
out.write(b);
System.err.println("AES Key Length: " + b.length);
}

out.write(iv);
System.err.println("IV Length: " + iv.length);

Cipher ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
ci.init(Cipher.ENCRYPT_MODE, skey, ivspec);

File inputDataFile = new File("dataFile.xml");
try (DataInputStream in = new DataInputStream(new FileInputStream(inputDataFile))) {
byte[] buffer = new byte[(int)inputDataFile.length()];
in.readFully(buffer);
in.close();
byte[] encryptedData = ci.doFinal(buffer);
out.write(encryptedData);
out.close();
}
}

}


public static void decryptRSAAES() throws Exception {

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, generatePrivateKey(readKeysFromFile("My_private.key")));

File file2 = new File("dataFile.enc");
RandomAccessFile raf = new RandomAccessFile(file2, "r");

// length of AES key
byte[] c = new byte[384];

// read the AES key from file
raf.read(c, 0 , 384);
byte[] fileContent = Files.readAllBytes(file2.toPath());
byte[] keyb = cipher.doFinal(c);
SecretKeySpec skey = new SecretKeySpec(keyb, "AES");

// read the initializatoin vector
byte[] iv = new byte[128/8];
raf.seek(384);
raf.read(iv);
IvParameterSpec ivspec = new IvParameterSpec(iv);

raf.seek(400);

Cipher ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
ci.init(Cipher.DECRYPT_MODE, skey, ivspec);
try (FileOutputStream out = new FileOutputStream("decryptedFileTest"+".xml")){

byte[] decryptedData = ci.doFinal(fileContent);
out.write(decryptedData);
out.close();
//processDecryptFile(ci, in, out);
}
}

实际结果:使用 AES key 和原始纯数据创建解密文件

预期结果:在输出中仅写入原始纯数据,删除 AES 和初始化 vector 。

最佳答案

让我们简化一下并使用 Java 的 InputStream 中新提供的功能类(class):

public static void encrypt(RSAPublicKey publicKey) throws Exception {

try (FileOutputStream out = new FileOutputStream("dataFile" + ".enc")) {

// --- RSA using PKCS#1 v1.5 padding
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);

// --- AES key generator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey skey = kgen.generateKey();

// --- write encrypted AES key
byte[] encryptedSKey = cipher.doFinal(skey.getEncoded());
out.write(encryptedSKey);

// --- Initialization vector 16 byte
SecureRandom srandom = new SecureRandom();
byte[] iv = new byte[128/8];
srandom.nextBytes(iv);
IvParameterSpec ivspec = new IvParameterSpec(iv);

// --- write IV
out.write(iv);


// --- initialize AES cipher
Cipher ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
ci.init(Cipher.ENCRYPT_MODE, skey, ivspec);

// --- convert file by copying to memory
try (FileInputStream in = new FileInputStream("dataFile.xml")) {
byte[] buffer = in.readAllBytes();
byte[] encryptedData = ci.doFinal(buffer);
out.write(encryptedData);
}
}
}


public static void decrypt(RSAPrivateKey privateKey) throws Exception {

try (FileInputStream in = new FileInputStream("dataFile" + ".enc")) {

// --- RSA using PKCS#1 v1.5 padding
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);

// --- read encrypted AES key
byte[] encryptedSKey = in.readNBytes(determineEncryptionSizeInBytes(privateKey));

byte[] decryptedSKey = cipher.doFinal(encryptedSKey);
SecretKey skey = new SecretKeySpec(decryptedSKey, "AES");

// --- Initialization vector 16 byte
byte[] iv = in.readNBytes(128 / Byte.SIZE);
IvParameterSpec ivspec = new IvParameterSpec(iv);

// --- initialize AES cipher
Cipher ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
ci.init(Cipher.DECRYPT_MODE, skey, ivspec);

// --- convert file by copying to memory
File outputDataFile = new File("dataFile.xml2");
try (FileOutputStream out = new FileOutputStream(outputDataFile)) {
byte[] buffer = in.readAllBytes();
byte[] decryptedData = ci.doFinal(buffer);
out.write(decryptedData);
}
}
}

private static int determineEncryptionSizeInBytes(RSAPrivateKey privateKey) {
return (privateKey.getModulus().bitLength() + Byte.SIZE - 1) / Byte.SIZE;
}

public static void main(String[] args) throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(384 * Byte.SIZE);
KeyPair pair = kpg.generateKeyPair();
encrypt((RSAPublicKey) pair.getPublic());
decrypt((RSAPrivateKey) pair.getPrivate());
}

正如您所看到的,代码现在更像是镜像。我只是复制了加密代码,然后对其进行了更改。正如您所看到的,它现在通过依赖 InputStream#readAllBytes() 使用更少的类。 (自 Java 9 起)和 InputStream#readNBytes() (自 Java 11 起)。

请注意,您通常希望使用较小的缓冲区文件。由于整个明文密文当前都在缓冲,您的应用程序使用的内存比所需的多得多。要使用流加密数据,您可以依靠 CipherInputStreamCipherOutputStream .

不用说异常处理需要改进,我只是简单地研究了解决您当前问题的最佳方法。当您让事情正常运转时(让事情正常运转、让事情正确、让事情优化),请再看一下它。

关于JAVA 将 AES key 、初始化 vector 和数据从加密文件中分离出来,并在加密过程中使用这 3 种组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55709517/

26 4 0
文章推荐: java - 将文件复制到 Java 中的双存档中(一个 zip 文件位于另一个 zip 文件中)
文章推荐: c++ - 无法推断函数返回类型
文章推荐: java - 复制jar中的 `export`命令来设置环境变量
文章推荐: java - 如何使用 JPA native 查询将 List 转换为 POJO