我在这里几乎搜索了有关此主题的所有主题,但我仍然不知道怎么了。我在Android应用程序上创建了3个EditText
: EditText
您将密钥/密码插入加密和解密; EditText2
在其中显示加密文本; EditText3
在其中显示解密文本。
由于它仍然是早期测试,因此我将消息或字符串放在应用中的变量中。
问题在于加密给出了类似Blowfish算法的东西,因此没有问题(以2 ==结束,所以我认为它正确地工作了)。我还尝试在解密前解码字符串或使用加密的RAW byte[]
,而没有任何好结果。解密不会回馈原始的字符串文本,而是提供比加密文本更大的东西。我对洪水的模式不偏爱,所以我开始轻松地开始使用blowfish/cfb/nopadding。
str_key
, str2
和 str3
暂时宣布为公开。str2
将设置EditText2
字段的文本,str3
将设置EditText3
字段的文本。输出的一个示例:从应用程序生成的输出的示例
这是代码:
public void encrypt(){
//encrypt
EditText mEdit = (EditText)findViewById(R.id.editText);
str_key = (String) mEdit.getText().toString();
int iterationCount = 1000;
int keyLength = 256;
int saltLength = keyLength / 8;
SecureRandom random = new SecureRandom();
byte[] salt = new byte[saltLength];
random.nextBytes(salt);
KeySpec keySpec = new PBEKeySpec(str_key.toCharArray(), salt,
iterationCount, keyLength);
SecretKeyFactory keyFactory = null;
try {
keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
byte[] keyBytes = new byte[0];
try {
keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
SecretKey key = new SecretKeySpec(keyBytes, "Blowfish");
Cipher cipher = null;
try {
cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
}
if ( cipher == null || key == null) {
//throw new Exception("Invalid key or cypher");
str2="error";
}
else {
byte[] iv = new byte[cipher.getBlockSize()];
random.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);
try {
cipher.init(Cipher.ENCRYPT_MODE, key,ivParams);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
try {
raw = cipher.doFinal(message.getBytes("UTF-8"));
} catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {
e.printStackTrace();
}
str2 = Base64.encodeToString(raw,Base64.DEFAULT);
}
}
这是解密函数:
public void decrypt(){
int iterationCount = 1000;
int keyLength = 256;
int saltLength = keyLength / 8;
SecureRandom random = new SecureRandom();
byte[] salt = new byte[saltLength];
random.nextBytes(salt);
KeySpec keySpec = new PBEKeySpec(str_key.toCharArray(), salt, iterationCount, keyLength);
SecretKeyFactory keyFactory = null;
try {
keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
byte[] keyBytes = new byte[0];
try {
keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
SecretKey key = new SecretKeySpec(keyBytes, "Blowfish");
Cipher cipher2 = null;
try {
cipher2 = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
}
iv = new byte[cipher2.getBlockSize()];
random.nextBytes(iv);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
try {
cipher2.init(Cipher.DECRYPT_MODE, key, ivSpec );
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
byte[] decryptedBytes = null;
byte[] app= Base64.decode(str2,Base64.DEFAULT);
try {
decryptedBytes = cipher2.doFinal(app);
} catch (IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
str3 = Base64.encodeToString(decryptedBytes,Base64.DEFAULT);
}
您将加密结果编码为base64,但是当您解密时,您将占据base64的普通字节。取而代之的是Base64首先解码以获取Ciphertext的实际字节阵列,然后解密。
您还直接从UTF8字节阵列中得出密钥,这是一种非常糟糕的方法。您应该使用KDF。PBKDF2是这里最常用的。
产生静脉输液的方式(根本不产生一个)也很差。它应随机生成并预添加到密文。它不需要秘密,只是无法预测。
最后,您根本不使用HMAC,因此任何人都可以更改密文,并且您不知道。