我想创建一个简单的应用程序来使用AES加密/解密邮件。 我的代码现在似乎正常工作,因为我得到文本加密和解密没有问题。
我有一个输入字段,一个输入解密/加密密码的字段和一个输出字段。 和两个按钮(加密/解密)。
问题是****,当我输入邮件并设置密码并对其进行加密,然后尝试激活无效的密码例外时,尽管输入的密码与密码不匹配,但邮件仍会解密我用于加密。
这是我生成密钥的代码:
public void vers(){
// Das Passwort bzw der Schluesseltext
keyStr = keyedit.getText().toString();
// byte-Array erzeugen
try {
key = (keyStr).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// aus dem Array einen Hash-Wert erzeugen mit MD5 oder SHA
try {
sha = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
key = sha.digest(key);
// nur die ersten 128 bit nutzen
key = Arrays.copyOf(key, 16);
// der fertige Schluessel
secretKeySpec = new SecretKeySpec(key, "AES");
}
这里是我加密邮件的代码:
private void codealgo() {
vers();
// der zu verschl. Text
text1 = input.getText().toString();
// Verschluesseln
try {
cipher = Cipher.getInstance("AES");
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
encrypted = cipher.doFinal(text1.getBytes());
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// bytes zu Base64-String konvertieren (dient der Lesbarkeit)
geheim = Base64.encodeToString(encrypted, Base64.NO_WRAP);
// Ergebnis
output.setText(geheim);
}
至少在这里我尝试再次解密邮件的代码:
private void decodealgo() {
vers();
geheim2 = input.getText().toString();
// BASE64 String zu Byte-Array konvertieren
data = Base64.decode(geheim2, Base64.NO_WRAP);
// Entschluesseln
try {
cipher3 = Cipher.getInstance("AES");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
cipher3.init(Cipher.DECRYPT_MODE, secretKeySpec2);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
Toast.makeText(getApplicationContext(), "Invalid key",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
try {
cipherData3 = cipher3.doFinal(data);
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
Toast.makeText(getApplicationContext(), "No valid encryption",
Toast.LENGTH_SHORT).show();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
Toast.makeText(getApplicationContext(), "Key invalid format",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
try {
text3 = new String(cipherData3, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Klartext
output.setText(text3);
}
请告诉我为什么解密过程会忽略密码以及随机条目显示已使用密码加密的消息的原因。
非常感谢你!
答案 0 :(得分:0)
您似乎几乎在任何变量中使用字段。您可以将此与使用应用程序的全局变量等同起来,尽管这是在类级别上执行的。应尽量减少类的字段数量(尽管不应将同一字段用于多种用途)。相反,您应该使用局部变量来处理不需要在方法之间共享的任何内容。
例如,所有关键相关变量都是当前字段。您最后只需要一个SecretKey
实例来加密/解密,因此所有这些变量都应该在本地变量中(尽管如此,您可以将密钥派生放在单独的方法中)。此外,您应该只使用密钥作为encrypt
和decrypt
方法的参数。这样你就没有机会突然将某个字段留给以前的值。共享Cipher
实例总是一个坏主意,特别是如果您不能保证将使用相同的密钥。
最后请注意,"AES/ECB/PKCS5Padding"
(Cipher.getInstance("AES")
可能暗示的可能会抛出BadPaddingException
,但即使是密钥或密文也无法保证为了提供密文的完整性和真实性,你必须在密文上使用(H)MAC.ECB模式本身只提供一定程度的机密性。可能最容易为你切换到GCM模式加密。
最后,密码不是密钥,搜索PBKDF2以获取更多信息。不要使用MD5。