2013-11-27 40 views
4

我的目标是使用AES algorithm编写一个Java程序来加密文本文件(cipher text)。然后,编写另一个程序来解密该加密文件(cipher text)以获取纯文本。我想使用相同的密钥(相同的密钥,生成一次,保存在某个地方,并将其用于加密和解密程序)进行加密和解密过程。如果我生成密钥并在同一个程序中逐行执行加密和解密,那么它可以很好地工作。这里是该工作代码片段:如何在Java中生成一次密钥并在两个不同的程序中使用该密钥

 String strDataToEncrypt = new String(); 
     String strCipherText = new String(); 
     String strDecryptedText = new String(); 

     KeyGenerator keyGen = KeyGenerator.getInstance("AES"); 
     keyGen.init(128); 
     SecretKey secretKey = keyGen.generateKey(); 

     Cipher aesCipher = Cipher.getInstance("AES"); 
     aesCipher.init(Cipher.ENCRYPT_MODE,secretKey); 

     strDataToEncrypt = "any text input"; 
     byte[] byteDataToEncrypt = strDataToEncrypt.getBytes(); 
     byte[] byteCipherText = aesCipher.doFinal(byteDataToEncrypt); 
     strCipherText = new BASE64Encoder().encode(byteCipherText); 
     System.out.println("cipher text: " +strCipherText); 
     aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters()); 
     byte[] byteDecryptedText = aesCipher.doFinal(new BASE64Decoder().decodeBuffer(strCipherText)); 
     strDecryptedText = new String(byteDecryptedText); 
     System.out.println("plain text again: " +strDecryptedText); 

但是,我需要有两个不同的程序(java文件)进行加密和解密。所以,我必须以某种方式生成一个密钥并保存在某个地方。然后对加密和解密程序使用相同的密钥。我怎样才能做到这一点?

EDIT_1

KeyGenerator keyGen = KeyGenerator.getInstance("AES"); 
keyGen.init(128); 
SecretKey secretKey = keyGen.generateKey(); 
byte[] encoded = secretKey.getEncoded(); 
System.out.println("key: "+encoded);// key: [[email protected] 

我可以使用上述程序编码的键值。但我的问题是如何在解密程序中使用此值生成SecretKey?

+0

您生成了一个密钥,什么阻止您将其写入文件,然后在第二个程序中读取它? –

+0

@JimGarrison请看看我的编辑。 –

+0

关键是系统使用'Object#toString()'的'byte []',它只是写出内部身份。您需要将单个字节_values_写入文件,也许先将它们转换为十六进制。 –

回答

11

原谅我,如果我误解了你的问题,但我相信你希望从现有的密钥编码重建SecretKey对象在一个字节数组中。

这可以简单地通过使用javax.crypto.spec.SecretKeySpec的构造这样进行:

byte[] encoded = //Key data 

SecretKey secretKey = new SecretKeySpec(encoded, "AES"); 

SecretKeySpec由于是SecretKey一个子类不需要铸造。如果您的加密/解密算法改变,请确保将构造函数AES中使用的字符串文字更改为您将来决定使用的任何算法。

+1

谢谢,我使用Base64Coder将密钥转换为十六进制字符串并保存到首选项,然后检索密钥并使用Base64Coder对其进行解码,并完美运行。 – Diljeet

1

这里的一个的方式打印出来的值在byte[]阵列中的十六进制:

byte[] a = {-120, 17, 42,121}; 
for (byte b : a) 
{ 
    System.out.printf("%2X",b); 
} 
System.out.println(); 
+0

我也可以使用:Arrays.toString(byte []) 来获取字节数组的内容。但是,我不确定如何使用此值初始化SecretKey。仍然在挖掘它。 –

+0

如果使用'Arrays.toString(byte [])',你将经历一个字节到字符的编码转换,这个转换可能是不可逆的。 –

+0

['Arrays.toString(byte [])'](http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#toString(byte []))被定义为产生非常不可能改变的阵列的标准表示。但是我同意这绝对不适合这个目的。 @KeenLearner考虑十六进制或Base64编码,如果你需要用ASCII码表示密钥,并且记住文件可以包含二进制数据。 – ntoskrnl

相关问题