我需要有关Android应用程序加密/解密的帮助。
我解释一下情况。我实际上编写了一个使用由iPhone应用程序生成和加密的内容的应用程序。
对于证券化,用户提供自己的密码来正确加密/解密不同平台之间的数据......
但是,我在Android上加密/解密了这个密码短语。
我有两个功能:
public byte[] crypt(String pStringToCrypt) throws Exception{
byte[] key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
System.arraycopy(this.passphrase.getBytes(), 0, key, 0, this.passphrase.getBytes().length);
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(pStringToCrypt.getBytes());
return encrypted;
}
用于加密String,以及此函数:
public String decrypt(byte[] pCryptedStringtoDecrypt) throws Exception{
byte[] key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
System.arraycopy(this.passphrase.getBytes(), 0, key, 0, this.passphrase.getBytes().length);
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
byte[] encrypted = pCryptedStringtoDecrypt;
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] original = cipher.doFinal(encrypted);
String originalString = new String(original);
return originalString;
}
用于解密String。
当我使用crypt方法加密数据时,我没有错误并且字符串已加密:
encrypted = [26, 119, -108, -24, 81, -128, 18, 35, -96, 10, -38, 69, 111, 40, 109, 107]
如果我尝试将此字节转换为字符串,我会获得此字符串:
encryptedString = "w��Q�#�\n�Eo(mk"
我认为加密阶段很好。 现在当我尝试解密这个加密的String时,应用程序崩溃了:
javax.crypto.IllegalBlockSizeException: last block incomplete in decryption
at org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal(JCEBlockCipher.java:711)
at javax.crypto.Cipher.doFinal(Cipher.java:1090)
at org.vincentsaluzzo.lightrpc.common.security.AES256.decrypt(AES256.java:61)
at com.vincentsaluzzo.LoginBox.model.SettingsManager.getUserPassphrase(SettingsManager.java:67)
at com.vincentsaluzzo.LoginBox.mainActivity.onCreate(mainActivity.java:26)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1586)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1638)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:928)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3647)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
我不明白为什么会出现这个错误...
你有解决方案吗?或者对我有些解释?
答案 0 :(得分:2)
好的,在你所有评论的帮助下,我解决了我的问题。
我解释一下。我已经将我的两种方法转化为最简单的方法:
public byte[] crypt(byte[] toCrypt) throws Exception {
byte[] key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
System.arraycopy(this.passphrase.getBytes(), 0, key, 0, ((this.passphrase.getBytes().length < 16) ? this.passphrase.getBytes().length : 16));
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(toCrypt);
return encrypted;
}
和
public byte[] decryptt(byte[] toDecrypt) throws Exception {
byte[] key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
System.arraycopy(this.passphrase.getBytes(), 0, key, 0, ((this.passphrase.getBytes().length < 16) ? this.passphrase.getBytes().length : 16));
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] original = cipher.doFinal(toDecrypt);
return original;
}
很快,我在此方法中删除了所有转换为字符串。 我在Objective-C的其他项目中检查了我的方法。 我发现了问题:编码字符串!
有时,如果我加密/解密,我得到相同的字节数组,但有时,数组是不同的,因为我将这个加密的字节数组存入SharedPreference中的字符串。 当然,它可能是可能的,但我只是将字节放入一个新的字符串(字节)中,基本编码是UTF-8,这就是问题所在。
我用base 64编码解决了这个问题。我使用此处的Base64类:http://sourceforge.net/projects/iharder/files/base64/2.3/
并且在将加密的字节数组保存到SharedPreferences之前,我将它们编码为Base64编码,并且对于解密过程也是如此。
答案 1 :(得分:0)
通常,使用getBytes()
将字符串转换为加密中的字节并不是一件好事。您受到计算机上默认字符编码的支配。更好的是为加密和解密指定编码getBytes("UTF-8")
你没有显示调用代码,你确定你将字节数组(encrypted
)传递给解密函数而不是字节数组的字符串,你的“w Q # \ NEO(MK“?
ECB模式不安全且泄漏数据。您需要使用CBC模式或CTR模式来确保安全。