五種常見的加密算法及簡單使用

加密算法

  加密算法能夠分爲單向加密算法、對稱加密算法和非對稱加密算法。算法

  • 單向加密算法:只能加密不能解密,輸入是任意長度字符串,輸出是固定長度的字符串。常見的有MD算法、SHA算法,通常用於信息摘要。安全

  • 對稱加密算法:既能加密又能解密,而且加密解密使用相同的密鑰。常見的有AES、DES算法,通常用於數字簽名。dom

  • 非對稱加密算法:既能加密又能解密,密鑰成對出現,被公鑰加密的密文只能被私鑰解密,被私鑰加密的密文只能被公鑰解密。常見的有RSA算法,通常用於數字簽名。編碼

MD5算法

  輸入任意長度字符串,輸出32位16進制字符串。加密

public class Md5Util {

    private static MessageDigest md5;

    static{
        try{
            md5=MessageDigest.getInstance("MD5");
        }
        catch(NoSuchAlgorithmException ex){
            ex.printStackTrace();
        }
    }

    /** * MD5加密 * @param primitiveValue 原始值 * @return 加密值 */
    public  static byte[] encrypt(byte[] primitiveValue){
        md5.update(primitiveValue);
        return md5.digest();
    }
}
複製代碼

SHA1算法

  輸入任意長度字符串,輸出40位16進制字符串。spa

public class Sha1Until {
    private static MessageDigest sha1;

    static{
        try{
            sha1=MessageDigest.getInstance("SHA1");
        }
        catch(NoSuchAlgorithmException ex){
            ex.printStackTrace();
        }
    }

    /** * SHA1加密 * @param primitiveValue 原始值 * @return 加密值 */
    public  static byte[] encrypt(byte[] primitiveValue){
        sha1.update(primitiveValue);
        return sha1.digest();
    }
}
複製代碼

  MD5和SHA1是相似的,不事後者的安全性更強一些,它們通常用於信息摘要,以確保數據不被篡改。code

HMAC算法

  HMAC算法是以單向加密算法爲基礎,添加密鑰,以確保數據不被僞造。cdn

public class HmacUtil {

    /** * HMAC加密 * @param key 密鑰 * @param primitiveValue 原始值 * @return 加密值 */
    private  static byte[] encrypt(byte[] key,byte[] primitiveValue,String algorithm){
        try{
            SecretKey secretKey = new SecretKeySpec(key,algorithm);
            Mac mac=Mac.getInstance(algorithm);
            mac.init(secretKey);
            return mac.doFinal(primitiveValue);
        }
        catch(InvalidKeyException | NoSuchAlgorithmException ex){
            ex.printStackTrace();
            return null;
        }
    }

    /** * HMAC加密,使用MD5 * @param key 密鑰 * @param primitiveValue 原始值 * @return 加密值 */
    public static byte[] encryptByMd5(byte[] key,byte[] primitiveValue){
        return encrypt(key,primitiveValue,"HmacMD5");
    }

    /** * HMAC加密,使用SHA1 * @param key 密鑰 * @param primitiveValue 原始值 * @return 加密值 */
    public static byte[] encryptBySha1(byte[] key,byte[] primitiveValue){
        return encrypt(key,primitiveValue,"HmacSHA1");
    }
}
複製代碼

AES算法

  AES算法是對稱加密算法。blog

public class AesUtil {
    private static SecretKeySpec keySpec;
    private static IvParameterSpec iv;
    private static Cipher cipher;

    static{
        try {
            cipher = Cipher.getInstance("AES/CFB/NoPadding");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void init(byte[] aesKey) {
        if ((aesKey.length == 16)||(aesKey.length==24)||(aesKey.length==32)) {
            keySpec = new SecretKeySpec(aesKey, "AES");
            iv = new IvParameterSpec(Md5Util.encrypt(aesKey));
        }
        else{
            throw new RuntimeException("密鑰長度無效,只能是1六、24或32字節");
        }
    }

    /** * AES加密 * @param key 密鑰 * @param primitivaValue 原始值 * @return 加密值 */
    public static byte[] encrypt(byte[] key,byte[] primitivaValue) {
        init(key);
        try {
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
            return  cipher.doFinal(primitivaValue);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /** * AES解密 * @param key 密鑰 * @param encryptedValue 加密值 * @return 原始值 */
    public static byte[] decrypt(byte[] key,byte[] encryptedValue) {
        init(key);
        try {
            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
            return cipher.doFinal(encryptedValue);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}
複製代碼

RSA算法

  RSA是非對稱加密算法。ip

public class RsaUtil {
    private static Cipher cipher;

    static{
        try {
            cipher = Cipher.getInstance("RSA");
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            e.printStackTrace();
        }
    }

    /** * 生成密鑰對 * @param keySize 密鑰對長度 * @param seed 隨機數種子 * @return 密鑰對 */
    public static KeyPair generateKeyPair(int keySize,byte[] seed){
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            keyPairGen.initialize(2048,new SecureRandom(seed));
            return  keyPairGen.generateKeyPair();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /** * 得到密鑰經base64編碼後文本 * @param key 密鑰 * @return 文本 */
    public static String getKeyText(Key key) {
        return (new BASE64Encoder()).encode(key.getEncoded());
    }

    /** * 加密 * @param key 密鑰 * @param primitiveValue * @return 原始值 */
    public static String encrypt(Key key, String primitiveValue){
        try {
            cipher.init(Cipher.ENCRYPT_MODE,key);
            byte[] enBytes = cipher.doFinal(primitiveValue.getBytes());
            return (new BASE64Encoder()).encode(enBytes);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /** * 解密 * @param key 密鑰 * @param encryptedValue 加密值 * @return */
    public static String decrypt(Key key, String encryptedValue){
        try {
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] deBytes = cipher.doFinal((new BASE64Decoder()).decodeBuffer(encryptedValue));
            return new String(deBytes);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
複製代碼

典型應用

數字簽名

  數字簽名,就是一種身份認證的方式。數字簽名一般定義兩種互補的操做,一個用於簽名,另外一個用於驗證。分別由發送者持有可以表明本身身份的私鑰 (私鑰不可泄露),由接受者持有與私鑰對應的公鑰(公鑰是公開的) ,可以在接受 到來自發送者信息時用於驗證其身份。

相關文章
相關標籤/搜索