"Your app contains unsafe cryptographic encryption patterns" - How I can get rid of this warning?

 

 

Asked 2 years, 2 months ago
Active 2 years ago
Viewed 5k times
 
7

Few days ago, In "Pre-launch report for APK" in Google Play Console, it start to flag me

Unsafe encryption

Detected in APK ???

Your app contains unsafe cryptographic encryption patterns. Please see this Google Help Centre article for details.

Vulnerable classes:

c.j.a.s.J.b

enter image description here


However, since the early day of APK, I do not change anything in encryption code/ description code. Hence, I'm not sure why Google starts to warn me on recent APK?

Any idea how to resolve? As, the information for vulnerable classes c.j.a.s.J.b is not helpful.

I try to use Proguard + mapping.txt to retrace c.j.a.s.J.b but able to figure what class is that.

Any idea how I can get rid of Google security warning?

  •  
    Did you find any solution.?   Sep 20 '19 at 6:40
  •  
    Not really. I did not find any solution.   Sep 20 '19 at 17:25
  •  
    Is there a class in the resources with each part of the fully qualifying name starting with letters c then j then a and so on? For example: com.java.android.sample.Java...
    – Boris
     Sep 24 '19 at 11:39 
  •  
    Try to find the class that uses crypto like this question https://stackoverflow.com/questions/58026804/unsafe-cryptographic-encryption-patterns-how-to-solve-it, you will see that the KEY is unsafe cryptographic encryption. I resolved it by use Android NDK Native.   Oct 3 '19 at 3:23 
  • 1
    I had the same issue and I didn't used any static key for encryption but the method was static and I changed it to normal class level method and it solved the issue   Nov 27 '19 at 5:42

2 Answers

2

The google play suggests with vulnerable classes with the function name, you can see in the dialog.

Review your app for statically computed keys, initialization vectors, and/or salts that are used in cryptographic encryption operations and ensure that these values are constructed safely

For example :

public byte[] encryptionUtil(String key, String iv, byte[] plainText) {
    Cipher cipher = Cipher.getInstance(“AES/GCM/NoPadding”);
    SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), “AES”);
    GCMParameterSpec paramSpec = new GCMParameterSpec(256, iv.getBytes());
    cipher.init(Cipher.ENCRYPT_MODE, keySpec, paramSpec);
    return cipher.doFinal(plainText);
  }

And you are calling a function as:

byte[] cipherText = encryptionUtil(“abcdef...”, “010203040506”, plainText);

Here your encryption key “abcdef...” is provides as a static string. A statically computed value is a value that is the same on every execution of your app. Statically computed cryptographic values can be extracted from your app and used to attack your app’s encrypted data.

So you can use EncryptedSharedPreferences to store locally data

Reference link https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences

OR

Jetpack Security

For more details: Remediation for Unsafe Cryptographic Encryption

  •  
    security-crypto library forcing to update min-sdk-version 26. Any solution for the lower version?   Nov 6 '19 at 7:03
 
-1

I think you are using some encryption/decryption code with statically stored key. A statically computed value is a value that is the same on every execution of your app. Statically computed cryptographic values can be extracted from your app and used to attack your app’s encrypted data. So Google give this warning to change that stored key with dynamically generated key. For that you can generate different key on every launch. To solve this problem generate dynamic encryption/decryption key on every launch. For that you can find more info here https://developer.android.com/jetpack/androidx/releases/security

  • 1
    What if you need to decrypt some data that was previously encrypted with a former key?   Sep 19 '19 at 5:36
  •  
    For that you can use asymmetric cryptography. which encrypt data with different private key and on other end decrypt data with public key. This link may help you. 
    – Mahesh
     Sep 19 '19 at 6:49 
  • 2
    How is it possible to have a single public key that can decrypt a message encrypted with a different private key? Aren't the keys generated as a standalone pair?   Sep 19 '19 at 11:20 
  •  
    I think, it's not related to original asked questions. Plz ask separate question. but you can get your questions answer from here
    – Mahesh
     Sep 23 '19 at 7:39
     
    https://stackoverflow.com/questions/58002913/your-app-contains-unsafe-cryptographic-encryption-patterns-how-i-can-get-rid
     
     
    #########################################################################################################################################################
     
     
     
    Asked 2 years, 2 months ago
    Viewed 2k times
     
    3
    This question already has answers here:
    Closed 2 years ago.

    I'm encrypting the password for firebase sign in, it's working well but I received a warning in google play console that your app contains unsafe cryptographic encryption patterns how can I get rid of it ??

    I'm trying it on 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;
        }
    
    •  
      What password? The user's password???   Sep 20 '19 at 11:41
    •  
      its email+salt   Sep 21 '19 at 11:32
    3
     
     

    The main issues are that you use a cipher with no integrity and a hard coded cryptographic key. If you analyse your source with Find Security Bugs you get CIPHER_INTEGRITY and HARD_CODE_KEY warning:

    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
    

    The solution is to use a cipher that includes a Hash based Message Authentication Code (HMAC) to sign the data:

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

    And to store the secret key in separate configuration files or keystores.

    Below is the whole class after a full refactoring:

    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);
      }
    }
    
    •  
      But, java.util.Base64 requires API level 26. What's the reason of using java.util.Base64 or android.util.Base64  Sep 22 '19 at 22:32
    •  
      Also, what is the implementation of Configuration.getKey()? If it is always returning the same value for different devices, will Google flag warning again?   Sep 22 '19 at 22:37
    •  
      @CheokYanCheng, can you share a link to the resource showing that you need the level 26 for a Java 8 class java.util.Base64
      – Boris
       Sep 23 '19 at 10:51
    • 1
      See developer.android.com/reference/java/util/Base64.Encoder (Added in API level 26)   Sep 23 '19 at 10:58
    • 1
      @Boris i remove hard code key now the warning gone thanks. :-)   Oct 10 '19 at 6:24
     

    Not the answer you're looking for? Browse other questions tagged    or ask your own question.

     

     

    https://stackoverflow.com/questions/58026804/unsafe-cryptographic-encryption-patterns-how-to-solve-it

posted @   a318013800  阅读(1262)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2020-12-02 jetpack
2018-12-02 ubuntu win7 双系统不能启动
2018-12-02 ubuntu16.04 虚拟机 安装win7/win10
2016-12-02 volley AAAAA
2016-12-02 Android开源项目分类汇总
2016-12-02 ubuntu输入法AAAAAA
点击右上角即可分享
微信分享提示