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

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