【问题标题】:unsafe cryptographic encryption patterns , How to solve it? [duplicate]不安全的密码加密模式,如何解决? [复制]
【发布时间】:2019-09-20 10:41:54
【问题描述】:

我正在加密 firebase 登录的密码,它运行良好,但我在 google play 控制台中收到了一条警告,your app contains unsafe cryptographic encryption patterns 我该如何摆脱它??

我正在android studio上尝试。

public static class AESCrypt
{
    private static final String ALGORITHM = "AES";
    private static final String KEY = "1Hbfh667adfDEJ78";

    public static String encrypt(String value) throws Exception
    {
        Key key = generateKey();
        Cipher cipher = Cipher.getInstance(AESCrypt.ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte [] encryptedByteValue = cipher.doFinal(value.getBytes("utf-8"));
        String encryptedValue64 = Base64.encodeToString(encryptedByteValue, Base64.DEFAULT);
        return encryptedValue64;

    }

    public static String decrypt(String value) throws Exception
    {
        Key key = generateKey();
        Cipher cipher = Cipher.getInstance(AESCrypt.ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decryptedValue64 = Base64.decode(value, Base64.DEFAULT);
        byte [] decryptedByteValue = cipher.doFinal(decryptedValue64);
        String decryptedValue = new String(decryptedByteValue,"utf-8");
        return decryptedValue;

    }

    private static Key generateKey() throws Exception
    {
        Key key = new SecretKeySpec(AESCrypt.KEY.getBytes(),AESCrypt.ALGORITHM);
        return key;
    }

【问题讨论】:

  • 什么密码?用户密码???
  • 它的电子邮件+盐

标签: java android firebase-authentication


【解决方案1】:

主要问题是您使用了不完整的密码和硬编码的加密密钥。如果您使用Find Security Bugs 分析您的源代码,您会收到CIPHER_INTEGRITYHARD_CODE_KEY 警告:

The cipher does not provide data integrity [com.lloyds.keystorage.AESCrypt] At AESCrypt.java:[line 25] CIPHER_INTEGRITY
The cipher does not provide data integrity [com.lloyds.keystorage.AESCrypt] At AESCrypt.java:[line 15] CIPHER_INTEGRITY
Hard coded cryptographic key found [com.lloyds.keystorage.AESCrypt] At AESCrypt.java:[line 35] HARD_CODE_KEY

解决方案是使用包含基于哈希的消息验证码 (HMAC) 的密码来签署数据:

Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

并将密钥存储在单独的配置文件或密钥库中。

下面是完整重构后的整个类:

import android.util.Base64
import static java.nio.charset.StandardCharsets.UTF_8;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class AESCrypt {
  private static final String TRANSFORMATION = "AES/GCM/NoPadding";

  public static String encrypt(String value) throws Exception {
    Key key = generateKey();
    Cipher cipher = Cipher.getInstance(TRANSFORMATION);
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] encryptedByteValue = cipher.doFinal(value.getBytes(UTF_8));
    return Base64.encodeToString(encryptedByteValue, Base64.DEFAULT);
  }

  public static String decrypt(String value) throws Exception {
    Key key = generateKey();
    Cipher cipher = Cipher.getInstance(TRANSFORMATION);
    cipher.init(Cipher.DECRYPT_MODE, key);
    byte[] decryptedValue64 = Base64.decode(value, Base64.DEFAULT);
    byte[] decryptedByteValue = cipher.doFinal(decryptedValue64);
    return new String(decryptedByteValue, UTF_8);
  }

  private static Key generateKey() {
    return new SecretKeySpec(Configuration.getKey().getBytes(UTF_8), TRANSFORMATION);
  }
}

【讨论】:

  • 但是,java.util.Base64 需要 API 级别 26。使用java.util.Base64android.util.Base64 的原因是什么?
  • 还有,Configuration.getKey()的实现是什么?如果它总是为不同的设备返回相同的值,谷歌会再次标记警告吗?
  • @CheokYanCheng,您能否分享一个资源链接,表明您需要 Java 8 类的级别 26 java.util.Base64
  • 参见developer.android.com/reference/java/util/Base64.Encoder(在 API 级别 26 中添加)
  • @Boris 我现在删除了硬代码密钥,警告消失了,谢谢。 :-)
猜你喜欢
  • 2016-04-28
  • 2011-07-14
  • 2011-10-24
  • 2014-11-20
  • 2011-07-10
  • 1970-01-01
  • 2012-01-26
  • 1970-01-01
相关资源
最近更新 更多