我在这里阅读了Java 256-bit AES Password-Based Encryption和其他几个条目。
我也看过这个:http://pastebin.com/YiwbCAW8
我在做什么: 我想用AES保护文件(users.dat),我只使用一串输出和输入流。
对象 - >密码 - >缓冲 - > FileOutputStream中
fileinputstream - >缓冲 - >密码 - >对象
因此,当我重新启动应用程序时,我想加载存储在该文件中的数据(users.dat)。
我在阅读文件时总是会遇到此异常( users.dat )。在先阅读 users.dat 之前,我从 key.dat
中读取了秘密字节java.io.StreamCorruptedException: invalid stream header: 7E000274
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:806)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at edu.hm.wedoit.usermanagement.impl.UserManagementImpl.loadUsers(UserManagementImpl.java:256)
at edu.hm.wedoit.usermanagement.impl.UserManagementImpl.<init>(UserManagementImpl.java:105)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:125)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:270)
//.... more spring
第一 如果没有密钥文件,我创建密钥并将其写入本地文件(key.dat)(未加密):
try(BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(keyFile)))
{
byte[] secretBytes = secret.getEncoded();
bos.write(secretBytes)
}
//catch
-32115-4061-70-102115-33-123-6494159-6-86115 (从简单的for循环输出,这些是写入文件的字节)
Keycreation代码:
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec("wedoit".toCharArray(), SALT, 65536, 128);
//note I only use 128 here because 256 doesnt work despite having local_policy.jar / US_export_policy.jar in {jdk}/lib/security
SecretKey tmp = factory.generateSecret(spec);
secretBytes = tmp.getEncoded();
secret = new SecretKeySpec(secretBytes, "AES");
saveSecret(secret); //saves the bytes to a simple file via object / ciper / buffered / fileoutputstream
Secdond 如果密钥文件存在,则在启动时,我从文件中读取字节。
-32115-4061-70-102115-33-123-6494159-6-86115(与上面的输出相同)
try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(keyFile)))
{
byte[] secretBytes = new byte[16];
bis.read(secretBytes);
return secretBytes;
}
//catch
对我来说,似乎写入/读取密钥文件似乎有效
secretBytes = loadKey();
secret = new SecretKeySpec(secretBytes, "AES"); // I thought the key will be reconstructed here?
所以这里有一些我用于密码初始化的代码。
encryptionCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] ivbyte = encryptionCipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
encryptionCipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(ivbyte));
decryptionCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
decryptionCipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivbyte));
更新 我使用try-with-resource(输入/输出)。
try(ObjectInputStream ois = new ObjectInputStream(
new CipherInputStream(new BufferedInputStream(new FileInputStream(userdbFile)),decryptionCipher)))
{
// .... ois.readObject();....
}
//...catch...
我做错了什么?
编辑稍微更新一下以澄清情况,我正在谈论的文件。到目前为止,感谢您的评论!
已经澄清:(搬到这里)
我注意到一些奇怪的东西,但我不知道它是否重要(连续调用,输出不同):
编辑:感谢评论中的jon
,似乎无法导入System.out.println(secret.getEncoded()); // [B@5c7e77fe
System.out.println(secret.getEncoded()); // [B@78b23edb
System.out.println(secret.getEncoded()); // [B@1e64a539