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

Java 加密算法

程序员文章站 2024-03-16 18:46:22
...

1. 散列算法

MD5和SHA主要通过采集文件的信息摘要,以此进行计算并加密。常被用来一致性验证、数字证书和安全访问认证。

MD5加密

MD5加密后的位数一般为两种,16位与32位。16位实际上是从32位字符串中,取中间的第9位到第24位的部分。

public class MD5 {	

    public static void encrypt(String value) {
        try {
            MessageDigest md = MessageDigest.getInstance("md5");
            md.update(value.getBytes());
            System.out.println("MD5:" + ByteTool.byte2hex(md.digest()));
        } catch (NoSuchAlgorithmException e) {			
        }
    }

}

ByteTool.java文件

public class ByteTool {
    private static String HexStr = "0123456789abcdef";

    public static String byte2hex(byte[] bytes) {
        String result = new String();
        for (byte b : bytes) {
            result = result + HexStr.charAt((b >> 4) & 0xF);
            result = result + HexStr.charAt(b& 0xF);
        }
        return result;
    }
}

"Hello World, This is a Test String!"输出

MD5:c1af26fa2188af7991b84a8db1e37c0d

SHA加密

SHA家族有五个算法,分别是SHA-1、SHA-224、SHA-256、SHA-384、SHA-512。

public class SHA {

    public static void encrypt(String algorithm, String value) {
        try {
            MessageDigest md = MessageDigest.getInstance(algorithm);
            md.update(value.getBytes());
            System.out.println(algorithm + ":" + ByteTool.byte2hex(md.digest()));
        } catch (NoSuchAlgorithmException e) {
        }
    }
}

SHA-1输出

SHA-1:ae4f2fc085b7e1dea58da3de3f7d5418ff6e59ff

SHA-256输出

SHA-256:e90d80449a1aa8aab9509403b924d420fc8df9b2ff9d2285938875d872ae3eb4

2. 对称加密

对称加密指加密和解密使用相同**的加密算法。

DES加密

DES是美国国家标准研究所提出的算法,加解密的数据安全性和**长度成正比。

public class DES {
    private static final String Algorithm = "DES";
    private static final byte[] Password = "13578642".getBytes();

    public static void encrypt(String value, byte[] password) {
        try {
            DESKeySpec desKey = new DESKeySpec(password);

            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
            SecretKey securekey = keyFactory.generateSecret(desKey);

            SecureRandom random = new SecureRandom();
            Cipher cipher = Cipher.getInstance(Algorithm);
            cipher.init(Cipher.ENCRYPT_MODE, securekey, random);

            System.out.println(Algorithm + ":" + ByteTool.byte2hex(cipher.doFinal(value.getBytes())));
        } catch (Exception e) {
        }
    }

    public static void decrypt(byte[] value, byte[] password) {
        try {
            DESKeySpec desKey = new DESKeySpec(password);

            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
            SecretKey securekey = keyFactory.generateSecret(desKey);

            SecureRandom random = new SecureRandom();
            Cipher cipher = Cipher.getInstance(Algorithm);
            cipher.init(Cipher.DECRYPT_MODE, securekey, random);

            System.out.println(Algorithm + ":" + new String(cipher.doFinal(value)));
        } catch (Exception e) {
        }

    }
}

输出

DES:4bf8e50bb824399876b476d415017c8656e89652550bcb2ffdd42d36edd7de2072a7ed4cc5cbfbde

ByteTool把输出转化成byte数组,并进行解密

public class ByteTool {
    private static String HexStr = "0123456789abcdef";

    public static byte[] hex2byte(String value) {
        byte[] result = new byte[value.length() / 2];
        for (int i = 0; i < result.length; i++) {
		    result[i] = (byte) Integer.parseInt(value.substring(i*2, i*2 + 2), 16);
        }
        return result;
    }

}

解密结果为

DES:Hello World, This is a Test String!

加密参数transformation

可以指定不同的transformation来进行加密算法。这个参数分为三段,加解密算法/工作模式/填充方式。 常采用的是NoPadding(不填充)、Zeros填充(0填充)、PKCS5Padding填充。

工作模式,详情可参考Java 块加密

  • ECB模式,又称电子密码本模式(Electronic codebook),是最简单的块密码加密模式。
  • CBC模式,密码分组链接(Cipher-block chaining)模式。
  • PCBC,填充密码块链接(Propagating cipher-block chaining)或称为明文密码块链接(Plaintext cipher-block chaining)
  • CFB,密文反馈(CFB,Cipher feedback)模式
  • OFB,OFB模式(输出反馈:Output feedback)
  • CTR,CTR模式(Counter mode,CM)也被称为ICM模式(Integer Counter Mode,整数计数模式)和SIC模式(Segmented Integer Counter)

指定

public class DES {
    private static final String Algorithm = "DES";
    private static final String Transformation = "DES/CBC/PKCS5Padding";
    private static final byte[] Password = "13578642".getBytes();
    private static final byte[] IvParameter = "12345678".getBytes();

    public static void encryptTransformation(String value, byte[] password) {
        try {
            DESKeySpec desKey = new DESKeySpec(password);

            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
            SecretKey securekey = keyFactory.generateSecret(desKey);

            IvParameterSpec iv = new IvParameterSpec(IvParameter);
            Cipher cipher = Cipher.getInstance(Transformation);
            cipher.init(Cipher.ENCRYPT_MODE, securekey, iv);

            System.out.println(Algorithm + ":" + ByteTool.byte2hex(cipher.doFinal(value.getBytes())));
        } catch (Exception e) {
        }
    }

    public static void decryptTransformation(byte[] value, byte[] password) {
        try {
            DESKeySpec desKey = new DESKeySpec(password);

            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
            SecretKey securekey = keyFactory.generateSecret(desKey);

            IvParameterSpec iv = new IvParameterSpec(IvParameter);
            Cipher cipher = Cipher.getInstance(Transformation);
            cipher.init(Cipher.DECRYPT_MODE, securekey, iv);

            System.out.println(Algorithm + ":" + new String(cipher.doFinal(value)));
        } catch (Exception e) {
        }
    }

}

输出

DES:7eb90b79d6d43b006add77fe406d8727ab01e09aa506618ea995319216e6ead632fdfced012ed865

3DES加密

3DES是DES加密算法的一种模式,它使用3条64位的**对数据进行三次加密,提高了安全强度。不过desede算法处理速度较慢,**计算时间较长,加密效率不高。

修改相关算法为DESede,其中password必须为24位。

public class DESede {
    private static final String Algorithm = "DESede";
    private static final String Transformation = "DESede/CBC/PKCS5Padding";
    private static final byte[] Password = "123456781234567812345678".getBytes();
    private static final byte[] IvParameter = "12345678".getBytes();;

    public static void encryptTransformation(String value, byte[] password) {	
        try {
            SecretKey securekey = new SecretKeySpec(password, Algorithm);

            IvParameterSpec iv = new IvParameterSpec(IvParameter);
            Cipher cipher = Cipher.getInstance(Transformation);
            cipher.init(Cipher.ENCRYPT_MODE, securekey, iv);

            System.out.println(Algorithm + ":" + ByteTool.byte2hex(cipher.doFinal(value.getBytes())));
        } catch (Exception e) {
        }
    }

    public static void decryptTransformation(byte[] value, byte[] password) {
        try {
            SecretKey securekey = new SecretKeySpec(password, Algorithm);

            IvParameterSpec iv = new IvParameterSpec(IvParameter);
            Cipher cipher = Cipher.getInstance(Transformation);
            cipher.init(Cipher.DECRYPT_MODE, securekey, iv);

            System.out.println(Algorithm + ":" + new String(cipher.doFinal(value)));
        } catch (Exception e) {
        }
    }
}

输出

DESede:c37551bb77f741d0b00f2f4e819bbdbcfac4e0c0095b9b9e231bf4e19a1d904bffafd60765749948

AES加密

AES是一个迭代的、对称**分组的密码,它可以使用128、192和256位**,并且用128位(16字节)分组加密和解密数据。

下面例子使用128位**加密,如果**大于128, 会抛出java.security.InvalidKeyException: Illegal key size异常,可参考这里

public class AES {
    private static final String Algorithm = "AES";
    private static final String Transformation = "AES/CBC/PKCS5Padding";
    private static final byte[] Password = "1234567812345678".getBytes();
    private static final byte[] IvParameter = "1234567887654321".getBytes();

    public static void encryptTransformation(String value, byte[] password) {
        try {
            SecretKey securekey = new SecretKeySpec(password, Algorithm);

            IvParameterSpec iv = new IvParameterSpec(IvParameter);
            Cipher cipher = Cipher.getInstance(Transformation);
            cipher.init(Cipher.ENCRYPT_MODE, securekey, iv);

            System.out.println(Algorithm + ":" + ByteTool.byte2hex(cipher.doFinal(value.getBytes())));
	    } catch (Exception e) {
	    }
    }

    public static void decryptTransformation(byte[] value, byte[] password) {
	    try {
            SecretKey securekey = new SecretKeySpec(password, Algorithm);

            IvParameterSpec iv = new IvParameterSpec(IvParameter);
            Cipher cipher = Cipher.getInstance(Transformation);
            cipher.init(Cipher.DECRYPT_MODE, securekey, iv);

            System.out.println(Algorithm + ":" + new String(cipher.doFinal(value)));
        } catch (Exception e) {		
	    }
    }
}

输出

AES:8642be6ffca8e366e01c06478a23906e531131079ab0e6da7ff5888a033fb5221a26d2161f66e60bcee53b2ee1314cc2