Cipher encryption using Java classes, including DES, DES3, AES and RSA encryption

First, look at a simple encryption, decryption achieve

1.1 Encryption

/ ** 
 * Content: encrypted content 
 * slatKey: encryption salts, 16-bit string 
 * vectorKey: encryption vector, 16-bit string 
 * / 
public String the encrypt (String Content, slatKey String, String vectorKey) throws Exception { 
    the Cipher cipher Cipher.getInstance = ( "the AES / the CBC / PKCS5Padding" ); 
    a secretKey secretKey = new new SecretKeySpec (slatKey.getBytes (), "the AES" ); 
    IvParameterSpec IV = new new IvParameterSpec (vectorKey.getBytes ()); 
    cipher.init (the Cipher. ENCRYPT_MODE, secretKey, IV); 
    byte [] = ENCRYPTED Cipher.doFinal (content.getBytes ());
     return Base64.encodeBase64String(encrypted);
}

1.2 decryption

/ ** 
 * Content: decrypting the content (Base64 encoded format) 
 * slatKey: salt used for encryption, 16-bit string 
 * vectorKey: vector used for encryption, 16-bit string 
 * / 
public String the decrypt (base64Content String, String slatKey , String vectorKey) throws Exception { 
    the cipher cipher = Cipher.getInstance ( "the AES / the CBC / PKCS5Padding" ); 
    a secretKey secretKey = new new SecretKeySpec (slatKey.getBytes (), "the AES" ); 
    IvParameterSpec IV = new new IvParameterSpec (vectorKey.getBytes ( )); 
    cipher.init (Cipher.DECRYPT_MODE, secretKey, IV); 
    byte [] Content = Base64.decodeBase64 (base64Content);
     byte[] encrypted = cipher.doFinal(content);
    return new String(encrypted);
}

 

 1.3 Code Explanation

Above a simple realization AES ( "AES / CBC / PKCS5Padding") encryption and decryption. We can see the code is mainly cipher object, with the following call

(1) need to pass a parameter "AES / CBC / PKCS5Padding" when new objects Cipher

(2) cipher objects required to initialize prior to use, a total of three parameters ( "encryption mode or decryption mode", "key", "vector")

(3) call data conversion: cipher.doFinal (content), where content is a byte array

In fact Cipher class implements a variety of encryption algorithms, when you create a Cipher object, passing different parameters can be different encryption algorithms. And of these different places just to create a key algorithms is different.

The incoming "AES / CBC / NoPadding" AES encryption can be performed, the incoming "DESede / CBC / NoPadding" can be DES3 encryption. Specific behind will be introduced to.

To reference built-in encryption algorithm Java, JDK documentation may refer to Appendix: https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html

Two, Java's Cipher class

2.1 Cipher class provides encryption and decryption capabilities.

The project uses Cipher class completed aes, des, des3 and rsa encryption.

Get Cipher class object: Cipher cipher = Cipher.getInstance ( "DES / CBC / PKCS5Padding"); parameter as "algorithm / mode / fill mode" has the following parameters

* The AES / the CBC / NoPadding (128)
* the AES / the CBC / PKCS5Padding (128)
* the AES / an ECB / NoPadding (128)
* the AES / an ECB / PKCS5Padding (128)
* the DES / the CBC / NoPadding (56 is)
* the DES / the CBC / PKCS5Padding (56 is)
* the DES / an ECB / NoPadding (56 is)
* the DES / an ECB / PKCS5Padding (56 is)
* a DESede / the CBC / NoPadding (168)
* a DESede / the CBC / PKCS5Padding (168)
* a DESede / an ECB / NoPadding (168)
* a DESede / an ECB / PKCS5Padding (168)
* the RSA / an ECB / PKCS1Padding (1024, 2048)
* the RSA / an ECB / OAEPWithSHA-1AndMGF1Padding (1024, 2048)
* the RSA / an ECB / OAEPWithSHA-256AndMGF1Padding (1024, 2048)
(. 1) encryption algorithm there are: AES, DES, DESede (DES3 ) and four kinds of RSA
(2) with a CBC mode (with a vector mode) and ECB (no vector mode), the vector mode may be understood as a simple offset, CBC mode requires a defined IvParameterSpec objects
(3) fill mode:
* NoPadding: the encrypted content is less than 8 with zeros 8, the Cipher class does not provide bit features, their implementation code required to add the encrypted content 0, {as} 65,65,65,0,0,0,0,0
* PKCS5Padding: the encrypted content is less than 8, more than made up by 8 bits, such as {} or {97,97,97,97,97,97,2 65,65,65,5,5,5,5,5, 2}; just fill 8 8 8

2.2 Cipher object needs to initialize

the init (int OPMODE, Key Key, an AlgorithmParameterSpec the params)
(. 1) OPMODE: Cipher.ENCRYPT_MODE (Encryption Mode) and Cipher.DECRYPT_MODE (decryption mode)
(2) Key: key using a pass key constructed salts, You can create keys to use SecretKeySpec, KeyGenerator and KeyPairGenerator, where
* SecretKeySpec and KeyGenerator support AES, DES, DESede three encryption algorithms to create a key
* KeyPairGenerator support RSA encryption algorithm to create a key
must be passed when using the CBC mode: (3) params the parameters of the project iv objects created using IvParameterSpec

2.3 encryption or decryption

byte [] b = cipher.doFinal (content );
return result byte array, if used as new String (b) encapsulated into a string, distortion occurs

Third, create a key

  The main key is created using SecretKeySpec, KeyGenerator and KeyPairGenerator three classes to create keys.

3.1 SecretKeySpec class

SecretKeySpec class supports the creation of key encryption algorithm (ASE, DES, DES3)

SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "AES");

But the main thing is the length of the required byte array of different encryption algorithms are different, to create a good idea to detect key length before the next byte array. The length of each key encryption algorithm is as follows

Encryption Algorithm Key length Vector length
AES 16 16
OF 8 8
DES3 24 8

 

 

 

 

3.2 KeyGenerator类

KeyGenerator class supports the creation of key encryption algorithm (ASE, DES, DES3)

 

   /**
     * 获取加密的密匙,传入的slatKey可以是任意长度的,作为SecureRandom的随机种子,
     * 而在KeyGenerator初始化时设置密匙的长度128bit(16位byte)
     */
    private static Key getSlatKey(String slatKey) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        random.setSeed(slatKey.getBytes());
        kgen.init(128, random);
        Key key = kgen.generateKey();
        return key;
    }

 

KeyGenerator对象在初始化需要传入一个随机源。一般使用的都是SecureRandom类来创建随机源,此时传入的盐只作为SecureRandom类的随机种子,种子相同,产生的随机数也相同;
盐的长度不再受限制了,但
KeyGenerator对象则必须指定长度。

3.3KeyPairGenerator类

RSA加密算法使用的密匙是包含公匙和私匙两种,一般情况下,有使用公匙加密,则用私匙解密;使用私匙加密,则使用公匙解密。可以使用KeyPairGenerator类来创建RSA加密算法的密匙

KeyPairGenerator类支持创建密匙的加密算法(RSA)

/**
     * 根据slatKey获取公匙,传入的slatKey作为SecureRandom的随机种子
     * 若使用new SecureRandom()创建公匙,则需要记录下私匙,解密时使用
     */
    private static byte[] getPublicKey(String slatKey) throws Exception {
        KeyPairGenerator keyPairGenerator  = KeyPairGenerator.getInstance("RSA");
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        random.setSeed(slatKey.getBytes());
        keyPairGenerator.initialize(1024, random);//or 2048
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        return keyPair.getPublic().getEncoded();
    }
    
    /**
     * 根据slatKey获取私匙,传入的slatKey作为SecureRandom的随机种子
     */
    private static byte[] getPrivateKey(String slatKey) throws Exception {
        KeyPairGenerator keyPairGenerator  = KeyPairGenerator.getInstance("RSA");
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        random.setSeed(slatKey.getBytes());
        keyPairGenerator.initialize(1024, random);// or 2048
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        return keyPair.getPrivate().getEncoded();
    }
同上,传入的盐只作为SecureRandom类的随机种子,盐相同,产生的keyPair的公匙和私匙也是同一对。
也可以不设置SecureRandom类的随机种子,直接使用new SecureRandom()创建一个新对象,此时就必须记录下公匙和私匙,在解密时使用。

四、对加密结果进行一层包装

4.1 针对1.3返回结果返回字符串乱码的问题,一般对byte数组进行处理

有两种处理方式:转换为base64的字符串或转换为16进制的字符串

4.2 转换为base64

使用apache下的Base64类进行封装即可,Base64.encodeBase64String(result); 结果形如 qPba5V+b0Ox3Um...
jar包下载:https://mvnrepository.com/artifact/commons-codec/commons-codec

4.3 转换为16进制

编码实现,即编码实现将2进制转换为16进制

/**
 * 16进制工具类
 */
public class HexUtil {
    private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

    /**
     * 十六进制转化为二进制
     */
    public static byte[] hexStrToByteArray(String hexString) {
        if (hexString == null) {
            return null;
        }
        if (hexString.length() == 0) {
            return new byte[0];
        }
        byte[] byteArray = new byte[hexString.length() / 2];
        for (int i = 0; i < byteArray.length; i++) {
            String subStr = hexString.substring(2 * i, 2 * i + 2);
            byteArray[i] = ((byte) Integer.parseInt(subStr, 16));
        }
        return byteArray;
    }

    /**
     * 二进制转化为十六进制
     */
    public static String byteArrayToHexStr(byte[] byteArray) {
        if (byteArray == null) {
            return null;
        }
        char[] hexChars = new char[byteArray.length * 2];
        for (int j = 0; j < byteArray.length; j++) {
            int v = byteArray[j] & 0xFF;
            hexChars[j * 2] = HEX_CHARS[v >>> 4];
            hexChars[j * 2 + 1] = HEX_CHARS[v & 0x0F];
        }
        return new String(hexChars);
    }
}

 

结果形如 04A2784A45234B.....

五、Java加密的代码

代码我上传到github上了,欢迎下载~~

https://github.com/caizhaokai/Java_Cipher_Encrypt

Guess you like

Origin www.cnblogs.com/caizhaokai/p/10944667.html