DH of Java encryption and decryption technology series

Source: Internet
Author: User
Tags base64 decrypt asymmetric encryption



Order
In the previous article, a simple introduction of an asymmetric encryption algorithm--rsa, today this article, continue to introduce another asymmetric encryption algorithm--DH. Of course, there may be many people who are not familiar with this encryption algorithm, but it doesn't matter, I hope this article can help you get acquainted with him today.

Concept
DH, known collectively as "Diffie-hellman", is a way to ensure that a shared key is securely traversing an unsecured network, which is often said to be a key-consistent protocol. An idea proposed by the founders of the public key Cryptosystem Diffie and Hellman.
simply put, allow two users to exchange information on public media to generate a "consistent", shareable key. That is, the output of a pair of key (public key, private key), party B in accordance with the public key to generate party B key pair (public key, private key).
as a baseline, the data is encrypted using the same symmetric encryption algorithm that is used to construct the local key (Secretkey). Thus, after exchanging the local key (Secretkey) algorithm, both parties expose their public key, encrypt the data using the other's public key and the private key just generated, and can use the other's public key and their private key to decrypt the data. Not only the two sides, can be extended to multi-party shared data communication, so that the network interactive data to complete the secure communication!

Principle
    • Communication Party A and communication party B contract an initial number g,g is public, such as g=5;
    • A generates a random number a,a is confidential, such as a=6;
    • A calculation g^a sent to b,g^a=5^6;
    • b Generate a random number b,b is confidential, such as b=15;
    • B calculation g^b sent to a,g^b=5^15;
    • A after receiving the g^b, then use the confidential A, calculate (g^b) ^a=g^ (a*b) =5^ (6*15);
    • b after receiving g^a, then use confidential B, calculate (g^a) ^b=g^ (a*b) =5^ (6*15);
    • This way the Communicator A and B get an identical "key" g^ (a*b) =5^ (6*15).

The whole communication process G, g^a, g^b is public, but because G, a, b are integers, by G and g^a get a or is relatively easy, B is so, so the final "key" g^ (a*b) can be calculated. So the actual process also needs to add a new computational-modulo operation to the basic principle.
  • Communication Party A and communication party B contract an initial number g, such as g=5, a prime p, such as P=23,G and p are public;
  • A generates a random number a,a is confidential, such as a=6;
  • A calculation g^a%p sent to b,g^a%p=5^6%23=8;
  • b Generate a random number b,b is confidential, such as b=15;
  • B calculation g^b%p sent to a,g^b%p=5^15%23=19;
  • A after receiving the g^b%p, then use the confidential A, calculate (g^b%p) ^a%p=19^6%23=2;
  • b After receiving the g^a%p, then use the confidential B, calculate (g^a%p) ^b%p=8^15%23=2;
  • So that the communication parties A and B get a same key: 2.

(g^b%p) ^a%p= (g^a%p) ^b%p proof:
If a=2:
    • (g^b%p) ^a%p= (g^b%p) ^2%p= (g^b-n*p) ^2%p= (g^ (2*b) -2*g^b*n*p+ (n*p) ^2)%p=g^ (2*b)%p;
    • Can be seen (g^b-n*p) ^2 after the expansion of the other than g^ (2*B), the other is a multiple of p, so the result of the entire calculation is g^ (2*b)%p;
    • Similarly to (g^b-n*p) ^a expansion, except g^ (A*b), the others are multiples of p, so the result of the whole calculation is g^ (a*b)%p;
    • The same can be obtained (g^a%p) ^b%p=g^ (a*b)%p;
    • So (g^b%p) ^a%p= (g^a%p) ^b%p.

The whole communication process G, p, g^a%p, g^b%p is public, at this time through G, p, g^a%p get a more difficult, also through G, p, g^b%p get B more difficult, so the final key is relatively safe.
Take g=5, p=23, g^a%p=8 to calculate a for example, A=log (5, (8+23*n)), this can only bring the possible values of n into the formula experiment to get the value of a. It is more difficult to calculate if a and p are relatively large numbers.
It should be noted that, in order to prevent the application of optimization algorithms to calculate the above problem, prime number p is not random choice, need to meet certain conditions. The generation algorithm of the random number A and B must also be noted that the results should be as random as possible and not predictable, otherwise it will make the crack easier.

Code implementation
<span style= "Font-family:comic Sans ms;font-size:12px;" >package Com.test.dh;import Com.google.common.collect.maps;import Sun.misc.base64decoder;import Sun.misc.base64encoder;import Javax.crypto.*;import Javax.crypto.interfaces.dhprivatekey;import Javax.crypto.interfaces.dhpublickey;import Javax.crypto.spec.dhparameterspec;import Java.security.*;import Java.security.spec.pkcs8encodedkeyspec;import Java.security.spec.x509encodedkeyspec;import java.util.Map;/** * Created by Xiang.li on 2015/3/4.    * DH Plus decryption Tool class */public class DH {/** * defines the encryption method */private static final String KEY_DH = "DH";    /** * Default key byte number */private static final int key_size = 1024;    /** * DH encryption requires a symmetric encryption algorithm for data encryption, here we use DES, we can also use other symmetric encryption algorithm */private static final String key_dh_des = "des";    private static final String Key_dh_publickey = "Dhpublickey";    private static final String Key_dh_privatekey = "Dhprivatekey"; /** * Initialize the party key * @return */public static Map<striNg, object> init () {map<string, object> Map = null;            try {keypairgenerator generator = keypairgenerator.getinstance (KEY_DH);            Generator.initialize (key_size);            KeyPair KeyPair = Generator.generatekeypair ();            Party a public key dhpublickey PublicKey = (dhpublickey) keypair.getpublic ();            Party a private key dhprivatekey Privatekey = (dhprivatekey) keypair.getprivate ();            Map = Maps.newhashmap ();            Map.put (Key_dh_publickey, PublicKey);        Map.put (Key_dh_privatekey, Privatekey);        } catch (NoSuchAlgorithmException e) {e.printstacktrace ();    } return map; }/** * Initialize Party B key * @param key Party key * @return */public static map<string, object> init (String k        EY) {map<string, object> Map = null;            try {//Resolve party key byte[] bytes = decryptBase64 (key); X509encodedkeyspec KeySpec = new X509encodedkeysPec (bytes);            Keyfactory factory = keyfactory.getinstance (KEY_DH);            PublicKey PublicKey = Factory.generatepublic (KeySpec);            Party B key Dhparameterspec spec = ((Dhpublickey) publickey) is constructed by the public key of party A. Getparams ();            Keypairgenerator generator = keypairgenerator.getinstance (KEY_DH);            Generator.initialize (spec);            KeyPair KeyPair = Generator.generatekeypair ();            Party b public key Dhpublickey Dhpublickey = (dhpublickey) keypair.getpublic ();            Party B private key Dhprivatekey Dhprivatekey = (dhprivatekey) keypair.getprivate ();            Map = Maps.newhashmap ();            Map.put (Key_dh_publickey, Dhpublickey);        Map.put (Key_dh_privatekey, Dhprivatekey);        } catch (Exception e) {e.printstacktrace ();    } return map;     }/** * DH encryption * @param data with encryption * @param publickey Party Public Key * @param Privatekey Party B private Key * @return */ public static byte[] ENCRYPTDH (byte[]Data, String PublicKey, String privatekey) {byte[] bytes = NULL;            try {//Generate local key Secretkey Secretkey = Getsecretkey (PublicKey, Privatekey);            Data encryption Cipher Cipher = Cipher.getinstance (Secretkey.getalgorithm ());            Cipher.init (Cipher.encrypt_mode, Secretkey);        bytes = cipher.dofinal (data);        } catch (NoSuchAlgorithmException e) {e.printstacktrace ();        } catch (Nosuchpaddingexception e) {e.printstacktrace ();        } catch (InvalidKeyException e) {e.printstacktrace ();        } catch (Badpaddingexception e) {e.printstacktrace ();        } catch (Illegalblocksizeexception e) {e.printstacktrace ();    } return bytes;     }/** * DH decryption * @param data to be decrypted * @param PublicKey Party B Public Key * @param Privatekey Party a private key * @return * * public static byte[] DECRYPTDH (byte[] data, String publickey, String privatekey) {byte[] bytes = NULL;            try {//Generate local key Secretkey Secretkey = Getsecretkey (PublicKey, Privatekey);            Data decryption Cipher Cipher = Cipher.getinstance (Secretkey.getalgorithm ());            Cipher.init (Cipher.decrypt_mode, Secretkey);        bytes = cipher.dofinal (data);        } catch (NoSuchAlgorithmException e) {e.printstacktrace ();        } catch (Nosuchpaddingexception e) {e.printstacktrace ();        } catch (InvalidKeyException e) {e.printstacktrace ();        } catch (Badpaddingexception e) {e.printstacktrace ();        } catch (Illegalblocksizeexception e) {e.printstacktrace ();    } return bytes; /** * Get the private key * @param map * @return */public static String Getprivatekey (map<string, object>        MAP) {String str = "";            try {Key key = (Key) map.get (Key_dh_privatekey);        str = encryptBase64 (key.getencoded ()); }catch (Exception e) {e.printstacktrace ();    } return str; /** * Get the public key * @param map * @return * * * static String Getpublickey (map<string, object> m        AP) {String str = "";            try {Key key = (Key) map.get (Key_dh_publickey);        str = encryptBase64 (key.getencoded ());        } catch (Exception e) {e.printstacktrace ();    } return str; /** * Build Local key * @param publickey public key * @param privatekey private key * @return * */private static Secretke        Y Getsecretkey (String publickey, String privatekey) {Secretkey secretkey = null;            try {//Initialize public key byte[] publicbytes = decryptBase64 (PublicKey);            Keyfactory factory = keyfactory.getinstance (KEY_DH);            X509encodedkeyspec KeySpec = new X509encodedkeyspec (publicbytes);            PublicKey Localpublickey = Factory.generatepublic (KeySpec); Initialize the private key byte[]Privatebytes = DecryptBase64 (Privatekey);            Pkcs8encodedkeyspec spec = new Pkcs8encodedkeyspec (privatebytes);            Privatekey Localprivatekey = factory.generateprivate (spec);            Keyagreement agreement = keyagreement.getinstance (Factory.getalgorithm ());            Agreement.init (Localprivatekey);            Agreement.dophase (Localpublickey, true);        Generate local Key Secretkey = Agreement.generatesecret (key_dh_des);        } catch (Exception e) {e.printstacktrace ();    } return Secretkey; }/** * BASE64 decryption * @param key The string to decrypt * @return byte array * @throws Exception */public static Byte    [] decryptBase64 (String key) throws Exception {return (new Base64decoder ()). Decodebuffer (key); }/** * BASE64 encryption * @param key required to encrypt byte array * @return String * @throws Exception */public static Stri Ng EncryptBase64 (byte[] key) throws Exception {return (new Base64encoder ()). Encodebuffer(key); }/** * Test method * @param args */public static void main (string[] args) {//Generate party key pair Map<s        Tring, object> MapA = init ();        String Publickeya = Getpublickey (MapA);        String Privatekeya = Getprivatekey (MapA);        System.out.println ("Party a public key: \ n" + Publickeya);        System.out.println ("Party a private key: \ n" + Privatekeya);        The local key is generated by the public key to map<string, object> MAPB = init (Publickeya);        String publickeyb = Getpublickey (MAPB);        String privatekeyb = Getprivatekey (MAPB);        System.out.println ("Party b public key: \ n" + publickeyb);        System.out.println ("Party B private key: \ n" + privatekeyb);        String word = "abc";        System.out.println ("Original:" + word);        By party a public key, party B private key construction ciphertext byte[] Encword = ENCRYPTDH (Word.getbytes (), Publickeya, privatekeyb);        By party B Public Key, party a private key decryption byte[] Decword = DECRYPTDH (Encword, Publickeyb, Privatekeya);    System.out.println ("Decrypt:" + new String (Decword)); }}</span><span style= "Font-family: Microsoft ya black; font-size:14px; " ></span>


Results





Conclusion
The trick of this mechanism is that both parties that need secure communication can use this method to determine the symmetric key. This key can then be used for encryption and decryption. Note, however, that this key exchange protocol/algorithm can only be used for exchange of keys, not for the encryption and decryption of messages. After both sides determine the key to be used, the encryption algorithm is actually encrypted and decrypted using the other symmetric key operations.

DH of Java encryption and decryption technology series

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.