当前位置: 首页 > 知识库问答 >
问题:

Android AES加密/解密忽略密码

陆和泰
2023-03-14

我想做一个简单的应用程序加密/解密与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);

}

请告诉我为什么密码会被解密过程忽略,以及为什么一个随机条目会显示用密码加密的消息。

共有1个答案

龚镜
2023-03-14

您似乎对几乎任何变量都使用字段。您可以将此等同于为应用程序使用全局变量,尽管这是在类级别上执行的。类的字段数量应该最小化(尽管不应该将同一个字段用于多个目的)。相反,您应该对不需要在方法之间共享的任何内容使用局部变量。

例如,所有与键相关的变量当前都是字段。您只需要一个secretkey实例来加密/解密,所以所有这些变量都应该在本地变量中(不过,您很好地将密钥派生放在一个单独的方法中)。此外,应该只将密钥用作encryptdecrypt方法的参数。这样就不会突然将某个字段保留到以前的值。共享cipher实例总是一个坏主意,尤其是在不能保证使用相同密钥的情况下。

最后,请注意“aes/ECB/pkcs5padding”(可能是cipher.getinstance(“aes”)所暗示的)可能会抛出badpaddingexception,但这并不保证,即使密钥或密文不正确。为了保证密文的完整性和真实性,您必须在密文上使用(H)MAC。ECB模式本身只提供一定程度的机密性。最简单的方法可能是切换到GCM模式加密。

最后,密码不是密钥,请搜索PBKDF2以获得更多信息。不要使用MD5。

 类似资料:
  • 问题内容: 我想用Java加密和解密密码,然后以加密形式存储到数据库中。如果它是开源的,那就太好了。有什么建议/建议吗? 问题答案: 编辑 :这个答案是旧的。现在 不建议 使用MD5,因为它很容易被破坏。 我想象中的MD5必须足够好?您可以使用MessageDigest实现它。 这里还列出了其他算法。 如果确实需要,这是它的第三方版本: Fast MD5

  • 我最近正在研究文件加密/解密。 当我尝试用相同的密钥解密文件时,总是会发生EVP_CipherFinal_ex。 代码片段将在下面发布。 我做错什么了吗? 谢谢你的帮助。 加密 解密 顺便说一句:当我使用CipherInputStream/CipherOutStream时,它会正常工作。我想知道是否可以只使用FileInputStream/FileOutputStream?非常感谢。 编辑:加密功

  • 我正在尝试使用javax.crypto.ciper加密/解密数据,其中我将转换指定为aes/ecb/pkcs5padding。 在我的本地机器中,jcesecurity.isrestricted()返回FALSE,但是当它在服务器上运行时,相同的方法返回true。由于服务器上的这种情况,系统不会为密码分配正确的权限。 不确定,JceSecurity restriction确切设置在哪里。感谢你的帮

  • 我理解哈希和加密之间的区别。我正在寻找一种在Python中实现加密/解密字符串的简单方法。我在网上找到的大多数方法都是关于使用散列算法(MD5-SHA-1等)来进行单向散列。但不幸的是,哈希是不可逆的。有什么建议吗?

  • 我有一个文本文件,我已经加密使用移位,但我需要加密加密的文本再次,但这一次使用vigenere密码。然后我需要解密加密的文本(首先是vigenere,然后是Shift),但所有的大小写字母以及黑色空格、引号、逗号和句号都需要保持不变。我已经完成了移位、加密和解密,剩下的就是Vigenere了。下面显示的是我加密Vigenere的类,我还没有写解密,因为我被卡在加密步骤。谢谢你。

  • 问题内容: 我有以下Go代码 输出是 使用以下CryptoJS加密 并且可以用解密 输出是-这是正确的输出 为什么Go会有不同的输出? 问题答案: 请检查您的错误。总是 https://play.golang.org/p/dRLIT51u4I 更具体地说,字节75处的值为,超出了base64可用字符的范围。在ascii中,它是ENQ(查询)字符。至于为什么它最终出现在您的最终base64字符串中,