欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android应用常用的加密方式

程序员文章站 2024-03-16 18:24:04
...
Android数据加密的方式,按加密的内容是否可以还原,可以分为可逆加密和非可逆加密。

非可逆加密: 加密后的数据不能还原成原来的数据,如MD5,sha1。
可逆加密: 可逆加密有一个公钥和一个私钥,通过公钥加密,私钥解密。常用的有:RSA,AES。

MD5

  • 使用场景:
    1.一致性验证,比如下载某个文件,不知道文件是否下载完成,可以MD5进行校验。加密文件比较耗时,应放到子线程中。
    2.密码的存储,如登陆注册这些,账号密码会保存到sp中,如果直接保存账号密码的MD5值。

  • 代码实现:

      /**
        *  使用md5方式进行加密
        *  @return
        */
      public static String digest(String content){
       StringBuilder builder = new StringBuilder();
       try {
           MessageDigest msgDitest = MessageDigest.getInstance("MD5");
           msgDitest.update(content.getBytes());
           byte[] digests = msgDitest.digest();
           //将每个字节转为16进制
           for (int i=0;i<digests.length;i++){
               builder.append(Integer.toHexString(digests[i] & 0xff +8));//+8为加盐操作
           }
       } catch (NoSuchAlgorithmException e) {
           e.printStackTrace();
       }
       return  builder.toString();
      }

RSA

  • 加密原理:
    1、随机选择两个大的质数P和Q,P不等于Q,计算出结果:N = PQ;
    2、选择一个大于1,小于N的自然数E,E必须和(P-1)
    (Q-1)互素;
    3、用公式计算出D:DE = mod(P-1)(Q-1);
    4、销毁P和Q。最终得到的N,E就是公钥,D就是私钥了。
  • 使用场景:
    项目中一些敏感的数据,比如身份证号,银行卡号,支付密码等相关敏感信息可以加密后再传输到服务端,服务端使用私钥进行解密。

-**对的生成:

    /*
      初始化KeyPairGenerator类,并获取到公钥和私钥
    */
    byte[] publicKeyByte;
    byte[] prvateKtyByte;

    public void getKey() {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(“RSA”);//KeyPairGenerator类是java专门提供生成**对的一个类。
            keyPairGenerator.initialize(1024); //设置**对的大小
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();//获取私钥
            PublicKey publicKey = keyPair.getPublic();//获取公钥
            prvateKtyByte = privateKey.getEncoded();//私钥对应的字节数组
            publicKeyByte = publicKey.getEncoded(); //公钥对应的字节数组

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

-公钥加密:

    public byte[] encryption(String content) {
        byte[] result = null;
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyByte);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            result = cipher.doFinal(content.getBytes());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return result;
    }
  • 私钥解密:
    public void decryption() {
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("RSA");
            //私钥需要通过PKCS8EncodedKeySpec来读取
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(prvateKtyByte);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            //生成私钥
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            //String content = "123456";
            byte[] input = encryption("123456");
            byte[] result = cipher.doFinal(input);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
    }

AES

  • 使用场景:AES是对称加密,加解密都是使用一个key,在项目中将一些敏感数据保存在本地,要使用时再取出来解密。

  • 代码实现:

public class AesUtils {
    /**
     * @param
     * @return AES加密算法加密
     */
    public static String encrypt(String seed, String key)
            throws Exception {
        byte[] rawKey = getRawKey(key.getBytes());
        byte[] result = encrypt(seed.getBytes("utf-8"), rawKey);
        return toHex(result);
    }

    public static byte[] encryptByte(String seed, String key)
            throws Exception {
        byte[] rawKey = getRawKey(key.getBytes());
        return encrypt(seed.getBytes("utf-8"), rawKey);
    }


    public static String decryptString(byte[] byteData, byte[] byteKey) throws Exception {
        byte[] rawKey = getRawKey(byteKey);
        byte[] result = decrypt(byteData, rawKey);
        return new String(result, "UTF8");
    }


    /***
     * AES加密算法加密
     * @param byteData 数据
     * @param byteKey key
     */
    private static byte[] encrypt(byte[] byteData, byte[] byteKey) throws Exception {
        return Ase(byteData, byteKey, Cipher.ENCRYPT_MODE);
    }

    /***
     * AES加密算法解密
     * @param byteData 数据
     * @param byteKey key
     */
    private static byte[] decrypt(byte[] byteData, byte[] byteKey) throws Exception {
        return Ase(byteData, byteKey, Cipher.DECRYPT_MODE);
    }


    /***
     *
     * @param byteData
     * @param byteKey
     * @param opmode
     */
    private static byte[] Ase(byte[] byteData, byte[] byteKey, int opmode) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        SecretKeySpec skeySpec = new SecretKeySpec(byteKey, "AES");
        cipher.init(opmode, skeySpec);
        byte[] decrypted = cipher.doFinal(byteData);
        return decrypted;
    }

    private static byte[] getRawKey(byte[] seed) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecureRandom sr = null;
        int sdk_version = android.os.Build.VERSION.SDK_INT;
        if (sdk_version > 23) {  // Android  6.0 以上
            sr = SecureRandom.getInstance("SHA1PRNG", new CryptoProvider());
        } else if (sdk_version >= 17) {
            sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
        } else {
            sr = SecureRandom.getInstance("SHA1PRNG");
        }
        sr.setSeed(seed);
        kgen.init(128, sr); // 192 and 256 bits may not be available
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        return raw;
    }


    public static class CryptoProvider extends Provider {
        /**
         * Creates a Provider and puts parameters
         */
        public CryptoProvider() {
            super("Crypto", 1.0, "HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature)");
            put("SecureRandom.SHA1PRNG",
                    "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
            put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
        }
    }


    private static String toHex(byte[] buf) {
        final String HEX = "0123456789ABCDEF";
        if (buf == null)
            return "";
        StringBuffer result = new StringBuffer(2 * buf.length);
        for (int i = 0; i < buf.length; i++) {
            result.append(HEX.charAt((buf[i] >> 4) & 0x0f)).append(
                    HEX.charAt(buf[i] & 0x0f));
        }
        return result.toString();
    }

    private static byte[] toByte(String hexString) {
        int len = hexString.length() / 2;
        byte[] result = new byte[len];
        for (int i = 0; i < len; i++)
            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
                    16).byteValue();
        return result;
    }
}
相关标签: Android数据加密