AndroidKeyStore的使用

密码算法使用:

1 对称加密:本地随机的密钥
方案:直接使用androidstore生成随机数,随机数做密钥

1.1 AES_CBC android 实现
函数主体:

public class AesCbcAlg{
    private static final String AndroidKeyStore = "AndroidKeyStore";
    private static final String AES_MODE_CBC = KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7;
    private static final String KEY_ALIAS = "AESCBCKEY";//这个别名
    public static byte[] cbc_iv = null;

    public static byte[] Encyption(String plaintext,SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance(AES_MODE_CBC);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encodedBytes = cipher.doFinal(plaintext.getBytes());
        //保存解密需要的IV变量
        cbc_iv = cipher.getIV();
        return encodedBytes;
    }

    public static byte[] Decyption(String encrypted) throws Exception {
        Cipher cipher = Cipher.getInstance(AES_MODE_CBC);
        KeyStore keyStore = KeyStore.getInstance(AndroidKeyStore);
        keyStore.load(null);
        SecretKey secretKey = (SecretKey) keyStore.getKey(KEY_ALIAS, null);
        cipher.init(Cipher.DECRYPT_MODE, secretKey,new IvParameterSpec(cbc_iv));
        byte[] decodedBytes = cipher.doFinal(Base64.decode(encrypted, Base64.DEFAULT));
        return decodedBytes;
    }

//上面这案例中是将IV保存到文件中,实际使用时,建议将IV保存到Data中,用于解密的时候使用,
    public static SecretKey createKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, AndroidKeyStore);
        keyGenerator.init(
                new KeyGenParameterSpec.Builder(KEY_ALIAS,

                    KeyProperties.PURPOSE_ENCRYPT |

KeyProperties.PURPOSE_DECRYPT)

.setBlockModes(KeyProperties.BLOCK_MODE_CBC)

.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
                    .build());
        //这里还有几个用户认证的程序需要搞定setUserAuthenticationRequired,setUserAuthenticationValidityDurationSeconds(int seconds)
        return keyGenerator.generateKey();
    }

}

验证函数:

public void CiperAesCbc(View view) throws Exception {
    String plaintext = "123456789012345" +
            "123456789012345" +
            "123456789012345" +
            "123456789012345";
    System.out.println(LOG_CBC_TAG + "加密明文为:" + plaintext);
    System.out.println(LOG_CBC_TAG + "加密模式为:CBC" );
    SecretKey secretKey = AesCbcAlg.createKey();

    System.out.println(LOG_CBC_TAG + "加密密钥为:" + secretKey);
    byte[] encodedBytes = AesCbcAlg.Encyption(plaintext, secretKey);
    String encryptedBase64Encoded = Base64.encodeToString(encodedBytes, Base64.DEFAULT);
    System.out.println(LOG_CBC_TAG + "加密结果为:" + encryptedBase64Encoded);

    byte[] decodedBytes = AesCbcAlg.Decyption(encryptedBase64Encoded);
    System.out.println(LOG_CBC_TAG + "初始向量为:" + AesCbcAlg.cbc_iv);
    System.out.println(LOG_CBC_TAG + "解密结果为:" + new String(decodedBytes, "UTF-8"));
}

1.2 AES_GCM android 实现
函数主体:

public class AesGcmAlg{
    private static final String AndroidKeyStore = "AndroidKeyStore";
    private static final String AES_MODE_GCM = KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
            + KeyProperties.ENCRYPTION_PADDING_NONE;
    private static final String KEY_ALIAS = "AESGCMKEY";

    public static byte[] gcm_iv = null;

    public static byte[] Encyption(String plaintext,SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance(AES_MODE_GCM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encodedBytes = cipher.doFinal(plaintext.getBytes());
        //保存解密需要的IV变量
        gcm_iv = cipher.getIV();
        return encodedBytes;
    }

    public static byte[] Decyption(String encrypted) throws Exception {
        Cipher cipher = Cipher.getInstance(AES_MODE_GCM);
        KeyStore keyStore = KeyStore.getInstance(AndroidKeyStore);
        keyStore.load(null);
        SecretKey secretKey = (SecretKey) keyStore.getKey(KEY_ALIAS, null);
        cipher.init(Cipher.DECRYPT_MODE, secretKey,new GCMParameterSpec(128, gcm_iv));
        byte[] decodedBytes = cipher.doFinal(Base64.decode(encrypted, Base64.DEFAULT));
        return decodedBytes;
    }
    public static SecretKey createKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, AndroidKeyStore);
        keyGenerator.init(
                new KeyGenParameterSpec.Builder(KEY_ALIAS,
                      KeyProperties.PURPOSE_ENCRYPT | 

KeyProperties.PURPOSE_DECRYPT)
                      .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                      .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                      .build());
        return keyGenerator.generateKey();
    }

}

验证函数

public void CiperAesGcm(View view) throws Exception {
    String plaintext = "123456789012345" +
            "123456789012345" +
            "123456789012345" +
            "123456789012345";
    System.out.println(LOG_GCM_TAG + "加密明文为:" + plaintext);
    System.out.println(LOG_GCM_TAG + "加密模式为:GCM" );
    SecretKey secretKey = AesGcmAlg.createKey();

    System.out.println(LOG_GCM_TAG + "加密密钥为:" + secretKey);
    byte[] encodedBytes = AesGcmAlg.Encyption(plaintext, secretKey);
    String encryptedBase64Encoded = Base64.encodeToString(encodedBytes, Base64.DEFAULT);
    System.out.println(LOG_GCM_TAG + "加密结果为:" + encryptedBase64Encoded);

    byte[] decodedBytes = AesGcmAlg.Decyption(encryptedBase64Encoded);
    System.out.println(LOG_GCM_TAG + "初始向量为:" + AesGcmAlg.gcm_iv);
    System.out.println(LOG_GCM_TAG + "解密结果为:" + new String(decodedBytes, "UTF-8"));

2 非对称加密:本地随机的密钥
方案:直接使用androidKeyStore生成,密钥对,不需要考虑密钥保存方案。

2.1 函数主体

public class RsaOaepCiper{
    private static final String AndroidKeyStore = "AndroidKeyStore";
    private static final String RSA_MODE_OAEP = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
    private static final String KEY_ALIAS = "RSACIPERKEY"; 

    public static byte[] Encyption(String plaintext) throws Exception {
        Cipher cipher = Cipher.getInstance(RSA_MODE_OAEP);
        KeyStore keyStore = KeyStore.getInstance(AndroidKeyStore);
        keyStore.load(null);
        PublicKey publicKey = keyStore.getCertificate(KEY_ALIAS).getPublicKey();
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encodedBytes = cipher.doFinal(plaintext.getBytes());
        return encodedBytes;
    }

    public static byte[] Decyption(String encrypted) throws Exception {
        Cipher cipher = Cipher.getInstance(RSA_MODE_OAEP);
        KeyStore keyStore = KeyStore.getInstance(AndroidKeyStore);
        keyStore.load(null);
        PrivateKey privateKey = (PrivateKey) keyStore.getKey(KEY_ALIAS, null);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decodedBytes = cipher.doFinal(Base64.decode(encrypted, Base64.DEFAULT));
        return decodedBytes;
    }
    public static KeyPair createKey() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, AndroidKeyStore);
        keyPairGenerator.initialize(
                new KeyGenParameterSpec.Builder(
                        KEY_ALIAS,
                        KeyProperties.PURPOSE_DECRYPT)
                        .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)

                        .setKeySize(2048)

//默认为2048,保险期间最好加上,否则容易扯皮
                        .build());
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        return keyPair;
    }
}

2.2 验证函数

public void CiperRsaOaep(View view) throws Exception {
    String plaintext = "123456789012345" +
            "123456789012345" +
            "123456789012345" +
            "123456789012345";
    System.out.println(LOG_RSA_OAEP_LOG + "加密明文为:" + plaintext);
    System.out.println(LOG_RSA_OAEP_LOG + "加密模式为:RSAOAEP" );
    KeyPair secretKey = RsaOaepCiper.createKey();

    System.out.println(LOG_RSA_OAEP_LOG + "RSA公钥为:" + secretKey.getPublic());
    System.out.println(LOG_RSA_OAEP_LOG + "RSA私钥为:" + secretKey.getPrivate());
    byte[] encodedBytes = RsaOaepCiper.Encyption(plaintext);
    String encryptedBase64Encoded = Base64.encodeToString(encodedBytes, Base64.DEFAULT);
    System.out.println(LOG_RSA_OAEP_LOG + "加密结果为:" + encryptedBase64Encoded);

    byte[] decodedBytes = RsaOaepCiper.Decyption(encryptedBase64Encoded);
    System.out.println(LOG_RSA_OAEP_LOG + "解密结果为:" + new String(decodedBytes, "UTF-8"));
}

3 数字签名
3.1 函数主体

public class RsaSignCiper{
    private static final String AndroidKeyStore = "AndroidKeyStore";
    private static final String RSA_MODE_SIGN = "SHA256withRSA/PSS";
    private static final String KEY_ALIAS = "RSASIGNCIPERKEY";//别名

    public static byte[] SignRsa(String plaintext) throws Exception {
        KeyStore keyStore = KeyStore.getInstance(AndroidKeyStore);
        keyStore.load(null);
        KeyStore.Entry entry = keyStore.getEntry(KEY_ALIAS, null);
        if (!(entry instanceof KeyStore.PrivateKeyEntry)) {
            Log.w("RSASIGN", "Not an instance of a PrivateKeyEntry");
            return null;
        }
        Signature signature = Signature.getInstance(RSA_MODE_SIGN);
        signature.initSign(((KeyStore.PrivateKeyEntry) entry).getPrivateKey());
        signature.update(plaintext.getBytes());
        byte[] signatureBytes = signature.sign();
        return signatureBytes;
    }

    public static Boolean VerifyRsa(String plaintext,byte[] signatureBytes) throws Exception {
        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);
        KeyStore.Entry entry = keyStore.getEntry(KEY_ALIAS, null);
        if (!(entry instanceof KeyStore.PrivateKeyEntry)) {
            Log.w("RSASIGN", "Not an instance of a PrivateKeyEntry");
            return null;
        }
        Signature signature = Signature.getInstance(RSA_MODE_SIGN);
        signature.initVerify(((KeyStore.PrivateKeyEntry) entry).getCertificate());
        signature.update(plaintext.getBytes());
        boolean valid = signature.verify(signatureBytes);
        return valid;
    }
    public static KeyPair createKey() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
                KeyProperties.KEY_ALGORITHM_RSA, AndroidKeyStore);
        keyPairGenerator.initialize(
                new KeyGenParameterSpec.Builder(
                        KEY_ALIAS,
                        KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                        .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                        .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS)

                        .setKeySize(2048)
                        .build());
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        return keyPair;
    }
}

3.2 验证函数

public void CiperRsaOaep(View view) throws Exception {
    String plaintext = "123456789012345" +
            "123456789012345" +
            "123456789012345" +
            "123456789012345";
    System.out.println(LOG_RSA_OAEP_LOG + "加密明文为:" + plaintext);
    System.out.println(LOG_RSA_OAEP_LOG + "加密模式为:RSAOAEP" );
    KeyPair secretKey = RsaOaepCiper.createKey();

    System.out.println(LOG_RSA_OAEP_LOG + "RSA公钥为:" + secretKey.getPublic());
    System.out.println(LOG_RSA_OAEP_LOG + "RSA私钥为:" + secretKey.getPrivate());
    byte[] encodedBytes = RsaOaepCiper.Encyption(plaintext);
    String encryptedBase64Encoded = Base64.encodeToString(encodedBytes, Base64.DEFAULT);
    System.out.println(LOG_RSA_OAEP_LOG + "加密结果为:" + encryptedBase64Encoded);

    byte[] decodedBytes = RsaOaepCiper.Decyption(encryptedBase64Encoded);
    System.out.println(LOG_RSA_OAEP_LOG + "解密结果为:" + new String(decodedBytes, "UTF-8"));
}

4 MAC算法
4.1 函数主体

public class MacCiper{
    private static final String AndroidKeyStore = "AndroidKeyStore";
    private static final String HMACMODE = "HmacSHA256";
    private static final String KEY_ALIAS = "HMACKEY";//这个非必要条件


    public static byte[] ServerSign(String plaintext,SecretKey secretKey) throws Exception {
        Mac mac = Mac.getInstance(HMACMODE);
        mac.init(secretKey);
        byte[] encodedBytes = mac.doFinal(plaintext.getBytes());
        return encodedBytes;
    }
    public static byte[] ClientSign(String plaintext) throws Exception {
        KeyStore keyStore = KeyStore.getInstance(AndroidKeyStore);
        keyStore.load(null);
        SecretKey secretKey = (SecretKey) keyStore.getKey(KEY_ALIAS, null);
        Mac mac = Mac.getInstance(HMACMODE);
        mac.init(secretKey);
        byte[] encodedBytes = mac.doFinal(plaintext.getBytes());
        return encodedBytes;
    }
    public static SecretKey createKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(
                KeyProperties.KEY_ALGORITHM_HMAC_SHA256, AndroidKeyStore);
        keyGenerator.init(
                new KeyGenParameterSpec.Builder(KEY_ALIAS, KeyProperties.PURPOSE_SIGN).build());
        SecretKey key = keyGenerator.generateKey();
        return key;
    }

}

4.2 验证函数

public void CiperHmac(View view) throws Exception{
    String plaintext= "123456789012345" +
            "123456789012345"+
            "123456789012345"+
            "123456789012345";
    Log.v(LOG_MAC_TAG, "消息明文为:" + plaintext);
    SecretKey secretKey= MacCiper.createKey();

    Log.v(LOG_MAC_TAG, "MAC密钥为:" + secretKey);
    byte[] encodedBytes= MacCiper.ServerSign(plaintext, secretKey);
    String encryptedBase64Encoded= Base64.encodeToString(encodedBytes, Base64.DEFAULT);
    Log.v(LOG_MAC_TAG, "签名结果为:" + encryptedBase64Encoded);

    byte[] decodedBytes= MacCiper.ClientSign(plaintext);
    Log.v(LOG_MAC_TAG, "认证结果为:" + Base64.encodeToString(encodedBytes, Base64.DEFAULT));

}

5 对称加密/非对称加密:固定密钥的保存(协商密钥)
方案:通过使用android_keystore使用RSA非对称加密算法对固定密钥进行保存,关于非对称加密的方案参考使用2.2(使用2.2的算法加密你的固定密钥,保存)

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值