## BASE64 and one-way encryption algorithm MD5&SHA&MAC

Encryption and decryption used to be an important component of my graduation project. Looking back on the encryption and decryption algorithms at the time after working for many years, it was too simple.
Closer to home, here we mainly describe some encryption and decryption algorithms that Java has implemented, and finally introduce digital certificates.
Such as the basic one-way encryption algorithm:

• Strictly speaking, BASE64 is an encoding format, not an encryption algorithm

• MD5 (Message Digest algorithm 5, message digest algorithm)

• SHA (Secure Hash Algorithm, secure hash algorithm)

• HMAC (Hash Message Authentication Code, hash message authentication code)

Complex symmetric encryption (DES, PBE), asymmetric encryption algorithm:

• DES (Data Encryption Standard, data encryption algorithm)

• RSA (the algorithm is named after the inventor: Ron Rivest, AdiShamir and Leonard Adleman)

• DH (Diffie-Hellman algorithm, key agreement agreement)

• DSA (Digital Signature Algorithm, digital signature)

• ECC (Elliptic Curves Cryptography, Elliptic Curve Cryptography)

This article briefly introduces several methods of BASE64 , MD5 , SHA , and HMAC . The three encryption algorithms of
MD5 , SHA , and HMAC can be described as irreversible encryption, that is, encryption methods that cannot be decrypted. We usually only use them as the basis for encryption. The encryption of the above three types is not reliable.

BASE64
is defined in RFC2045.Base64 is defined as: Base64 content transfer encoding is designed to describe any sequence of 8-bit bytes as a form that is not easy to be directly recognized by people. (The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.)
Commonly used in email, http encryption, intercept http information, you will find the username and password fields for login operations Encrypted by BASE64.

The implementation through java code is as follows:

`/**  * BASE64 decryption  *   * @param key  * @return  * @throws Exception  */  public static byte [] decryptBASE64(String key)  throws  Exception {        return  ( new  BASE64Decoder()).decodeBuffer(key);  }    /**  * BASE64 encryption  *   * @param key  * @return  * @throws Exception  */  public static  String encryptBASE64( byte [] key)  throws  Exception {       return  ( new  BASE64Encoder()).encodeBuffer(key);  }  `

Mainly there are two classes of BASE64Encoder and BASE64Decoder, we only need to know the corresponding method. In addition, the number of bytes generated after BASE encryption is a multiple of 8.If the number of bytes is not enough, it is filled with = sign.

MD5
MD5 - abbreviation of message-digest algorithm 5 (message-digest algorithm), widely used in encryption and decryption technology, often used in file verification. check? No matter how big the file is, a unique MD5 value can be generated after MD5. It is like the current ISO verification, which is all MD5 verification. how to use? Of course, the MD5 value is generated after the ISO passes through the MD5. Generally, friends who download linux-ISO have seen the MD5 string next to the download link. It is used to verify that the files are consistent.

The implementation through java code is as follows:

`/**  * MD5 encryption  *   * @param data  * @return  * @throws Exception  */  public static byte [] encryptMD5( byte [] data)  throws  Exception {          MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);      md5.update(data);        return  md5.digest();    }  `

Usually we do not directly use the above MD5 encryption. Usually the byte array generated by MD5 is handed over to BASE64 and then encrypted to obtain the corresponding string.

SHA
SHA (Secure Hash Algorithm), digital signature and other important tools in cryptographic applications are widely used in information security fields such as e-commerce. Although both SHA and MD5 have been cracked by the collision method, SHA is still a recognized secure encryption algorithm, which is more secure than MD5.

The implementation through java code is as follows:

`   /**      * SHA encryption      *       * @param data      * @return      * @throws Exception      */      public static byte [] encryptSHA( byte [] data)  throws  Exception {              MessageDigest sha = MessageDigest.getInstance(KEY_SHA);          sha.update(data);            return  sha.digest();        }  }  `

HMAC
HMAC (Hash Message Authentication Code, hash message authentication code, an authentication protocol based on the Hash algorithm of the key.The principle of the message authentication code to achieve authentication is to use a public function and a key to generate a fixed-length value as an authentication identifier.This identifier authenticates the integrity of the message.A key is used to generate a small data block of fixed size, that is, MAC, which is added to the message, and then transmitted.The receiver uses the key shared with the sender for authentication and so on.

The implementation through java code is as follows:

`/**  * Initialize the HMAC key  *   * @return  * @throws Exception  */  public static  String initMacKey()  throws  Exception {       KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);        SecretKey secretKey = keyGenerator.generateKey();      return  encryptBASE64(secretKey.getEncoded());  }    /**  * HMAC encryption  *   * @param data  * @param key  * @return  * @throws Exception  */  public static byte [] encryptHMAC( byte [] data, String key)  throws  Exception {          SecretKey secretKey =  new  SecretKeySpec(decryptBASE64(key), KEY_MAC);      Mac mac = Mac.getInstance(secretKey.getAlgorithm());      mac.init(secretKey);        return  mac.doFinal(data);    }  `

Give a complete class as follows:

`import  java.security.MessageDigest;    import  javax.crypto.KeyGenerator;  import  javax.crypto.Mac;  import  javax.crypto.SecretKey;    import  sun.misc.BASE64Decoder;  import  sun.misc.BASE64Encoder;    /**  * Basic encryption components  *   * @author Liang Dong  * @version 1.0  * @since 1.0  */  public abstract class  Coder {        public static final  String KEY_SHA =  "SHA" ;        public static final  String KEY_MD5 =  "MD5" ;          /**      * MAC algorithm can choose the following multiple algorithms      *       * <pre>      * HmacMD5       * HmacSHA1       * HmacSHA256       * HmacSHA384       * HmacSHA512      * </pre>      */      public static final  String KEY_MAC =  "HmacMD5" ;          /**      * BASE64 decryption      *       * @param key      * @return      * @throws Exception      */      public static byte [] decryptBASE64(String key)  throws  Exception {            return  ( new  BASE64Decoder()).decodeBuffer(key);      }        /**      * BASE64 encryption      *       * @param key      * @return      * @throws Exception      */      public static  String encryptBASE64( byte [] key)  throws  Exception {           return  ( new  BASE64Encoder()).encodeBuffer(key);      }        /**      * MD5 encryption      *       * @param data      * @return      * @throws Exception      */      public static byte [] encryptMD5( byte [] data)  throws  Exception {              MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);          md5.update(data);            return  md5.digest();        }        /**      * SHA encryption      *       * @param data      * @return      * @throws Exception      */      public static byte [] encryptSHA( byte [] data)  throws  Exception {              MessageDigest sha = MessageDigest.getInstance(KEY_SHA);          sha.update(data);            return  sha.digest();        }        /**      * Initialize the HMAC key      *       * @return      * @throws Exception      */      public static  String initMacKey()  throws  Exception {           KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);            SecretKey secretKey = keyGenerator.generateKey();          return  encryptBASE64(secretKey.getEncoded());      }        /**      * HMAC encryption      *       * @param data      * @param key      * @return      * @throws Exception      */      public static byte [] encryptHMAC( byte [] data, String key)  throws  Exception {              SecretKey secretKey =  new  SecretKeySpec(decryptBASE64(key), KEY_MAC);          Mac mac = Mac.getInstance(secretKey.getAlgorithm());          mac.init(secretKey);            return  mac.doFinal(data);        }  }  `

Give another test class:

`import static  org.junit.Assert.*;     import  org.junit.Test;    /**  *   * @author Liang Dong  * @version 1.0  * @since 1.0  */  public class  CoderTest {         @Test      public void  test()  throws  Exception {           String inputStr =  "Simple Encryption" ;          System.err.println( "Original:\n"  + inputStr);            byte [] inputData = inputStr.getBytes();          String code = Coder.encryptBASE64(inputData);            System.err.println( "After BASE64 encryption:\n"  + code);            byte [] output = Coder.decryptBASE64(code);            String outputStr =  new  String(output);            System.err.println( "BASE64 after decryption:\n"  + outputStr);            // Verify the consistency of BASE64 encryption and decryption          assertEquals(inputStr, outputStr);            // Verify that MD5 is consistent for the same content encryption          assertArrayEquals(Coder.encryptMD5(inputData), Coder                  .encryptMD5(inputData));            // Verify that SHA is consistent for the same content encryption          assertArrayEquals(Coder.encryptSHA(inputData), Coder                  .encryptSHA(inputData));            String key = Coder.initMacKey();          System.err.println( "Mac key:\n"  + key);            // Verify that HMAC is consistent with the same content and the same key encryption          assertArrayEquals(Coder.encryptHMAC(inputData, key), Coder.encryptHMAC(                  inputData, key));            BigInteger md5 =  new  BigInteger(Coder.encryptMD5(inputData));          System.err.println( "MD5:\n"  + md5.toString( 16 ));            BigInteger sha =  new  BigInteger(Coder.encryptSHA(inputData));          System.err.println( "SHA:\n"  + sha.toString( 32 ));            BigInteger mac =  new  BigInteger(Coder.encryptHMAC(inputData, inputStr));          System.err.println( "HMAC:\n"  + mac.toString( 16 ));      }  }  `

Console output:

`original:  Simple encryption  After BASE64 encryption:  566A5Y2V5Yqg5a+G    After BASE64 decryption:  Simple encryption  Mac key:  uGxdHC+6ylRDaik++leFtGwiMbuYUJ6mqHWyhSgF4trVkVBBSQvY/a22xU8XT1RUemdCWW155Bke  pBIpkd7QHg==    MD5:  -550b4d90349ad4629462113e7934de56  SHA:  91k9vo7p400cjkgfhjh0ia9qthsjagfn  HMAC:  2287d192387e95694bdbba2fa941009a  `

Note that
when you compile, you may see the following prompt:

`Warning: sun.misc.BASE64Decoder is Sun's private API,import sun.misc.BASE64Decoder may be removed in future versions ;               ^Warning: sun.misc.BASE64Encoder is Sun's private API,import sun may be removed in future versions.misc.BASE64Encoder;               ^`

BASE64Encoder and BASE64Decoder are unofficial JDK implementation classes. Although it can be found and used in the JDK, it is not available in the API. The classes beginning with sun and com.sun in JRE are not documented.They belong to the basis of java and javax class libraries.Most of the implementations are related to the underlying platform, and generally they are not recommended.

The encryption and decryption of BASE64 is bidirectional and can be reversed.
MD5, SHA, and HMAC are one-way encryption.After any data is encrypted, only one encrypted string will be generated, which is usually used to verify whether the data has been modified during transmission. Among them, the HMAC algorithm has a key, which enhances the security during data transmission and strengthens uncontrollable factors outside the algorithm.
The purpose of one-way encryption is mainly to verify whether the data has been modified during transmission.

#### Technical otaku

Sought technology together