我想加密和解密先前使用生成的AES密钥在SealedObject中加密的对象,这些对象在SealedObject中使用RSA进行持久化和加密。
Stack是我的项目库和Serializable的一部分。名为xxxStack的每个Object都是Stack的子类。
相关属性
// encrypted Object
private SealedObject stack;
// cache for the Object
private transient Stack stackCache;
// encrypted AES key
private SealedObject key;
// cache for AES key which is used to encrypt and decrypt the Object
private transient SecretKey keyCache;
使用唯一的AES密钥加密缓存对象(stackCache)的方法,然后使用公共RSA密钥加密并保存在堆栈中
public void encrypt(Cipher c0) throws IllegalBlockSizeException, IOException{
/*
* Creates unique AES key for encrypting the Object
*/
KeyGenerator keyGen = null;
try {
keyGen = KeyGenerator.getInstance("AES");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
keyGen.init(256);
keyCache = keyGen.generateKey();
/*
* Creating AES Cipher for encryption
*/
Cipher c1 = null;
try {
c1 = Cipher.getInstance("AES");
c1.init(Cipher.ENCRYPT_MODE, keyCache);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*
* Encrypts Object
*/
stack = new SealedObject(stackCache, c1);
/*
* Encrypts AES key with a Cipher given as argument (intended to be a public RSA key initialized Cipher)
*/
key = new SealedObject(keyCache, c0);
}
解密加密的AES密钥以使用它解密保存的对象的方法。参数c旨在成为RSA私钥初始化密码。
public void decrypt(Cipher c) throws ClassNotFoundException, IllegalBlockSizeException, BadPaddingException, IOException{
//decrypting the AES key (CryptoStack.java:110)
keyCache = (SecretKey) key.getObject(c);
//generating Cipher for decryption
Cipher c1 = null;
try {
c1 = Cipher.getInstance("AES");
c1.init(Cipher.DECRYPT_MODE, keyCache);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//decrypting Object with previous generated Cipher
stackCache = (Stack) stack.getObject(c1);
}
相关属性
//Connection to the Server
private Socket socket;
//InputStream
private ObjectInputStream oin;
//Listener for incoming data
private IncomingStackListener l;
//HashMap for caching PublicKeys
private ConcurrentHashMap<String, PublicKey> publicKeyCache = new ConcurrentHashMap<String, PublicKey>();
线程等待正在解密的传入数据给侦听器。
public void run() {
Stack stack = null;
while (!isInterrupted()) {
try {
stack = (Stack) oin.readObject();
/*Irrelevant code removed*/
// Detect and decrypt encrypted data
if (stack.getType().equals(StackType.ENCRYPTED)) {
Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.DECRYPT_MODE, me.getPrivateKey());
//following: Client.java:75
((CryptoStack) stack).decrypt(c);
stack = ((CryptoStack) stack).getCache();
}
} catch (ClassNotFoundException | IOException
| NoSuchAlgorithmException | NoSuchPaddingException
| InvalidKeyException | IllegalBlockSizeException
| BadPaddingException e) {
e.printStackTrace();
}
l.onStackEntry(stack);
}
}
在标准的JVM环境中,一切正常。 但是在Android应用程序中使用此代码(它是我的项目库的一部分),存储在SealedObject密钥中的唯一密钥的解密将失败,并伴随以下LogCat输出:
java.io.StreamCorruptedException
java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:2070)
java.io.ObjectInputStream.<init>(ObjectInputStream.java:371)
javax.crypto.SealedObject.getObject(SealedObject.java:220)
chat.protocol.secure.CryptoStack.decrypt(CryptoStack.java:110)
chat.client.core.Client.run(Client.java:75)
如何在Android上使用它? 如果需要解决方案,我已准备好提供更多代码
答案 0 :(得分:0)
所以我终于弄明白了问题所在。 在Android和其他&#34; PC&#34;之间使用加密跨平台时平台确保您指定算法,模式和填充(例如&#34; AES / CBC / PKCS5Padding&#34;),因为仅指定算法(如&#34; AES&#34;)似乎会引起误解。