Android DES,AES,RSA加密实现

DES加密:

DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位(每组的第8位作为奇偶校验位),产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 轮循环,使用异或置换代换移位操作四种基本运算。

Android中的使用还是比较简单的,java库中已经封装好了相应的接口,只需要按照规则进行调用即可。

private static String Algorithm = "DES";
private static String privKey = "";
/**
 * 加密
 *
 * @param input
 * @param key
 * @return
 * @throws Exception
 */
public static byte[] encryptData(byte[] input, byte[] key) throws Exception {
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
    DESKeySpec keySpec = new DESKeySpec(key);
    Key deskey = keyFactory.generateSecret(keySpec);
    Cipher c1 = Cipher.getInstance(Algorithm);
    c1.init(Cipher.ENCRYPT_MODE, deskey);
    byte[] cipherByte = c1.doFinal(input);
    return cipherByte;
}
/**
 * 解密
 *
 * @param input
 * @param key
 * @return
 * @throws Exception
 */
public static byte[] decryptData(byte[] input, byte[] key) throws Exception {
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
    DESKeySpec keySpec = new DESKeySpec(key);
    Key deskey = keyFactory.generateSecret(keySpec);

    Cipher c1 = Cipher.getInstance(Algorithm);
    c1.init(Cipher.DECRYPT_MODE, deskey);
    byte[] clearByte = c1.doFinal(input);
    return clearByte;
}




/**
 * 默认key
 *
 * @return
 */
public static byte[] getDefaultKey() {
    return privKey.getBytes();
}

AES加密:

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。

Android中的使用和DES的方法类似,只是在key的生成方式中有些不同。

private static String Algorithm = "AES";
   private static String privKey = "";
private static byte[] getRawKey(byte[] seed) throws Exception {
    KeyGenerator kgen = KeyGenerator.getInstance(Algorithm);
    SecureRandom sr = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
    } else {
        sr = SecureRandom.getInstance("SHA1PRNG");
    }
    sr.setSeed(seed);
    kgen.init(256, sr); // 192 and 256 bits may not be available
    SecretKey skey = kgen.generateKey();
    byte[] raw = skey.getEncoded();
    return raw;
}


public static byte[] encrypt(byte[] input) throws Exception {
    try {
        byte[] raw = getRawKey(privKey.getBytes());
        SecretKeySpec skeySpec = new SecretKeySpec(raw, Algorithm);
        Cipher cipher = Cipher.getInstance(Algorithm);

        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
        byte[] encrypted = cipher.doFinal(input);
        return encrypted;
    } catch (Exception e) {
        e.printStackTrace();
        return input;
    }
}

public static byte[] decrypt(byte[] encrypted) throws Exception {
    try {
        byte[] raw = getRawKey(privKey.getBytes());
        SecretKeySpec skeySpec = new SecretKeySpec(raw, Algorithm);
        Cipher cipher = Cipher.getInstance(Algorithm);
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    } catch (Exception e) {
        e.printStackTrace();
        return encrypted;
    }
}

RSA加密:

RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年首次公布,当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准

RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

Android中的实现方法和DES,AES比较相似。

private static final String PADDING = "RSA/None/PKCS1Padding";
private static final String ALGORITHM = "RSA";
private static final String PROVIDER = "BC";
private static final String ENCODDING = "UTF-8";
/**
 * 随机生成RSA密钥对
 *
 * @param keyLength
 *            密钥长度,范围:5122048
 *            一般1024
 * @return
 */
public static KeyPair generateRSAKeyPair(int keyLength) {
    try {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM, PROVIDER);
        kpg.initialize(keyLength);
        return kpg.generateKeyPair();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return null;
    } catch (NoSuchProviderException e) {
        e.printStackTrace();
        return null;
    }
}

/**
 * 用公钥加密
 * 每次加密的字节数,不能超过密钥的长度值减去11
 *
 * @param data
 *            需加密数据的byte数据
 * @param publicKey
 *            公钥
 * @return 加密后的byte型数据
 */
public static byte[] encryptData(byte[] data, PublicKey publicKey) {
    try {
        Cipher cipher = Cipher.getInstance(PADDING, PROVIDER);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    } catch (Exception e) {
        e.printStackTrace();
        return data;
    }
}

/**
 * 用私钥解密
 *
 * @param encryptedData
 *            经过encryptedData()加密返回的byte数据
 * @param privateKey
 *            私钥
 * @return
 */
public static byte[] decrpytData(byte[] encryptedData, PrivateKey privateKey) {
    try {
        Cipher cipher = Cipher.getInstance(PADDING, PROVIDER);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(encryptedData);
    } catch (Exception e) {
        e.printStackTrace();
        return encryptedData;
    }
}
有一点需要注意,在Android中默认的RSA加密时无padding的,及直接使用Cipher.getInstance("RSA")不会进行额外的数据填充,从而加密的密文每次都是相同,而使用PKCS1Padding填充模式时,即使每次的数据和秘钥相同,产生的密文也会不同,从而提高数据的安全性。

源码地址:http://download.csdn.net/detail/gxlgxjhll/9397206

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章