2012-12-15 99 views
0

我有一个java程序,用随机生成的密钥加密文件内容。 该密钥用RSA加密并保存到文本文件中。java - 从字节数组中获取密钥

现在,我有一个Java程序给出了存储RSA密钥的文件和密钥存储区,需要先解密已加密密钥,然后用密钥解密文件。

这是我到目前为止有:

// Fetch the other public key and decrypt the file encryption key 
java.security.cert.Certificate cert2 = keystore.getCertificate("keyForSeckeyDecrypt"); 
Key secKeyPublicKey = cert2.getPublicKey(); 
Cipher cipher = Cipher.getInstance(secKeyPublicKey.getAlgorithm()); 
cipher.init(Cipher.DECRYPT_MODE, secKeyPublicKey); 
keyFileFis = new FileInputStream(keyFile); 
byte[] encryptedKey = new byte[128]; 
keyFileFis.read(encryptedKey); 
byte[] realFileKey = cipher.doFinal(encryptedKey, 0, encryptedKey.length); 
Key realKey = // THE PROBLEM!!!; 
keyFileFis.close(); 

总之,我得到了关键的文本文件中的加密密钥和解密,现在我有解密密钥的字节数组,我会怎么做它又是一个关键变量?

我已经生成的关键是这样的:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
KeyGenerator keyGen = KeyGenerator.getInstance("AES"); 
Key secKey = keyGen.generateKey(); 
cipher.init(Cipher.ENCRYPT_MODE, secKey); 

和加密这样说:

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
kpg.initialize(1024); 
KeyPair kp = kpg.genKeyPair(); 
PrivateKey privateKey = kp.getPrivate(); 
Cipher keyCipher = Cipher.getInstance("RSA"); 
keyCipher.init(Cipher.ENCRYPT_MODE, privateKey); 
byte[] encryptedKey = keyCipher.doFinal(secKey.getEncoded()); 
FileOutputStream keyStream = new FileOutputStream("key.txt"); 
keyStream.write(encryptedKey); 
keyStream.close(); 
+0

你能分享你如何生成存储在文件密钥?算法?长度? – Akdeniz

+0

更新了我的文章 – MichBoy

+0

只是要确定!你使用“新生成的”RSA私钥加密你的'aes'键并保存到文件中。但你期望用你的密钥库中的公钥解密它!这对我没有意义。你应该使用keystore中的私钥来使它工作。 – Akdeniz

回答

1

我还没有尝试过,但是从点击通过API SecretKeySpec可能是你正在找。

SecretKeySpec(byte[] key, String algorithm) 

它可以用于构造从一个字节数组生成SecretKey,而不必经过一个(基于提供)SecretKeyFactory。

该类仅适用于可以表示为字节数组并且没有与它们相关联的关键参数的原密钥,例如DES或Triple DES密钥。

+0

我已经试过了,但是当我这样做时,尝试初始化密码与此SecretKeySpec,我得到一个异常“没有安装的提供程序支持此密钥:javax.crypto.spec.SecretKeySpec” – MichBoy

+0

@MichBoy这是重新创建密钥的正确方法。问题可能是您的钥匙尺寸不正确。 AES密钥应为16,24或32字节,而不是128.要使用长度超过128个字节的密钥,您需要正确安装无限强度管辖权策略文件。 – erickson

0

如果我得到它的权利,这应该工作..

Key privateKey = keyStore.getKey("youralias", "password".toCharArray()); 
PublicKey publicKey = keyStore.getCertificate("youralias").getPublicKey(); 

KeyGenerator keyGen = KeyGenerator.getInstance("AES"); 
Key secKey = keyGen.generateKey(); 

Cipher keyCipher = Cipher.getInstance("RSA"); 
keyCipher.init(Cipher.ENCRYPT_MODE, privateKey); 
byte[] encryptedKey = keyCipher.doFinal(secKey.getEncoded()); 

// Write & Read to/from file! 

Cipher decryptCipher = Cipher.getInstance("RSA"); 
decryptCipher.init(Cipher.DECRYPT_MODE, publicKey); 
byte[] decryptedKey = decryptCipher.doFinal(encryptedKey); 

boolean equals = Arrays.equals(secKey.getEncoded(), new SecretKeySpec(decryptedKey, "AES").getEncoded()); 
System.out.println(equals?"Successfull!":"Failed!"); 
+0

感谢您付出的巨大努力,提出以下几点要点:a)加密和解密分为两个不同的类别(即不同的程序),因此secKey在加密程序中,但在解密程序中不存在。 b)我仍然没有解决我的问题,因为我需要一个密钥变量来解密原始文件。 – MichBoy

+0

顺便说一下,出于某种原因,当试图执行decryptCipher.doFinal(encryptedKey)部分时,我得到“数据为零开始”异常,为什么? – MichBoy

+0

确保您可以准确读取您写入该文件的内容。顺便说一句,这段代码只是一个概念证明,你可以用'SecretKeySpec'重新创建你的'AES'密钥。如果您的背景有问题,请提出另一个问题,明确指出您的问题。 – Akdeniz