A common digital Signature algorithm RSA and DSA Java program implementation Example _java

Source: Internet
Author: User
Tags base64 decrypt asymmetric encryption


RSA encryption Algorithm
Let's review the RSA encryption algorithm. Based on the definition of public key encryption algorithm and signature algorithm, we describe this algorithm in a more canonical language. The
RSA public Key Cryptography system includes the following 3 algorithms: KeyGen (Key generation algorithm), Encrypt (cryptographic algorithm), and decrypt (decryption algorithm). The
Key generation algorithm takes a security constant as input, outputs a public key PK, and a private key SK. The security constants are used to determine how secure this cryptographic algorithm is, generally in relation to the size of the prime number p used by the cryptographic algorithm. The larger the prime number p is, the greater the security of the system. In RSA, the key generation algorithm is as follows: The algorithm first randomly generates two different large prime numbers p and Q, and computes N=PQ. Then, the algorithm computes the Euler function. Next, the algorithm randomly selects a less-than-integer e, and calculates e about the modulo inverse element d. Finally, the public key is pk= (n, e) and the private key is sk= (n, D). The
encryption algorithm outputs a ciphertext CT with the public key PK and message m to be encrypted as input. In RSA, the encryption algorithm is as follows: The algorithm directly output ciphertext to
decryption algorithm with the private key SK and ciphertext CT as input, output message m. In RSA, the decryption algorithm is as follows: the algorithm directly outputs plaintext. Because E and D are reciprocal inverses, so we have:
Therefore, we can see from the description of the algorithm that the public key is used to encrypt the data, and the private key is used to decrypt the data. Of course, this can also be intuitive to understand: Public key is the public key, it is public to use it to encrypt data. The private key is private, and whoever has the key can decrypt the text. Otherwise everyone can see the private key, can decrypt, that is not a mess.
Let's take a look at a simple implementation in Java:


package com.stone.security;
 
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Arrays;
 
import javax.crypto.Cipher;
 
/ **
 * RSA algorithm public key encryption asymmetric encryption
 * /
public class RSA {
 public static final String KEY_ALGORITHM = "RSA";
 public static final String CIPHER_ALGORITHM_ECB1 = "RSA / ECB / PKCS1Padding";
 public static final String CIPHER_ALGORITHM_ECB2 = "RSA / ECB / OAEPWithSHA-1AndMGF1Padding"; // Not available
 public static final String CIPHER_ALGORITHM_ECB3 = "OAEPWithSHA-256AndMGF1Padding"; // Cannot be used
 
 static PublicKey publicKey;
 static PrivateKey privateKey;
 static Cipher cipher;
 static KeyPair keyPair;
 
 public static void main (String [] args) throws Exception {
 method1 ("Skoda U * (Sfsad7f () * ^ %% $");
 method2 ("Skoda U * (Sfsad7f () * ^ %% $");
 method3 ("Skoda U * (Sfsad7f () * ^ %% $");
  
 }
 
 / **
 * Public key encryption, private key decryption Use the default CIPHER_ALGORITHM_ECB1
 * @param str
 * @throws Exception
 * /
 static void method1 (String str) throws Exception {
 KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance (KEY_ALGORITHM);
 KeyPair keyPair = keyGenerator.generateKeyPair ();
 publicKey = keyPair.getPublic ();
 privateKey = keyPair.getPrivate ();
 cipher = Cipher.getInstance (KEY_ALGORITHM);
 cipher.init (Cipher.ENCRYPT_MODE, publicKey); // Public key encryption
 byte [] encrypt = cipher.doFinal (str.getBytes ());
 System.out.println ("After public key encryption 1:" + Arrays.toString (encrypt));
  
 cipher.init (Cipher.DECRYPT_MODE, privateKey); // Decrypt private key
 byte [] decrypt = cipher.doFinal (encrypt);
 System.out.println ("After the private key is decrypted 1:" + new String (decrypt));
 }
 
 / **
 * Private key encryption, public key decryption Use the default CIPHER_ALGORITHM_ECB1
 * @param str
 * @throws Exception
 * /
 static void method2 (String str) throws Exception {
 KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance (KEY_ALGORITHM);
 KeyPair keyPair = keyGenerator.generateKeyPair ();
 publicKey = keyPair.getPublic ();
 privateKey = keyPair.getPrivate ();
 cipher = Cipher.getInstance (KEY_ALGORITHM);
 cipher.init (Cipher.ENCRYPT_MODE, privateKey); // private key encryption
 byte [] encrypt = cipher.doFinal (str.getBytes ());
 System.out.println ("2 after private key encryption:" + Arrays.toString (encrypt));
  
 cipher.init (Cipher.DECRYPT_MODE, publicKey); // Public key decryption
 byte [] decrypt = cipher.doFinal (encrypt);
 System.out.println ("After public key decryption 2:" + new String (decrypt));
 }
 
 / **
 * Private key encryption, public key decryption using CIPHER_ALGORITHM_ECB1 = RSA / ECB / PKCS1Padding
 * @param str
 * @throws Exception
 * /
 static void method3 (String str) throws Exception {
 KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance (KEY_ALGORITHM);
 KeyPair keyPair = keyGenerator.generateKeyPair ();
 publicKey = keyPair.getPublic ();
 privateKey = keyPair.getPrivate ();
 cipher = Cipher.getInstance (CIPHER_ALGORITHM_ECB1);
 cipher.init (Cipher.ENCRYPT_MODE, privateKey); // private key encryption
 byte [] encrypt = cipher.doFinal (str.getBytes ());
 System.out.println ("3 after private key encryption:" + Arrays.toString (encrypt));
  
 cipher.init (Cipher.DECRYPT_MODE, publicKey); // Public key decryption
 byte [] decrypt = cipher.doFinal (encrypt);
 System.out.println ("After public key decryption 3:" + new String (decrypt));
 }
}

The DSA algorithm and digital signature 

DSA are typically used for digital signatures and authentication. The
DSA is a variant of the Schnorr and ElGamal signature algorithm, which was used as a DSS (DigitalSignature Standard) by the United States NIST. The
DSA is based on the integer finite domain discrete logarithm problem, and its security is comparable to that of RSA.
in DSA digital signatures and authentication, the sender uses his or her private key to sign the file or message, and the recipient uses the sender's public key after receiving the message
to verify the authenticity of the signature. DSA is only an algorithm, and RSA is different because it can not be used as encryption and decryption, and can not be key exchange,
only for signature, it is much faster than RSA.


package com.stone.security;
 
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
 
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
 
/ **
 * DSA-Digital Signature Algorithm is a variant of Schnorr and ElGamal signature algorithms, and is used by the American NIST as DSS (DigitalSignature Standard).
 * To put it simply, this is a more advanced verification method used as a digital signature. Not only the public key and private key, but also the digital signature. Private key encryption generates digital signatures, public key verification data and signatures.
 * If the data and signature do not match, the verification is deemed to have failed! That is, the data in transmission can no longer be encrypted. After receiving the data, the receiver gets the public key and signature to verify whether the data is valid
 * /
public class DSA {
 / **
 * Not only DSA algorithm but also RSA algorithm can be used for digital signature
 * /
 public static final String KEY_ALGORITHM = "RSA";
 public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; * /
 
 public static final String KEY_ALGORITHM = "DSA";
 public static final String SIGNATURE_ALGORITHM = "DSA";
 
 public static final String DEFAULT_SEED = "$% ^ *% ^ () (HJG8awfjas7"; // default seed
 public static final String PUBLIC_KEY = "DSAPublicKey";
 public static final String PRIVATE_KEY = "DSAPrivateKey";
 
 public static void main (String [] args) throws Exception {
 String str = "! @ # $! # ^ $ # & ZXVDF Silent Military Road Loves You * () _ +";
 byte [] data = str.getBytes ();
  
 Map <String, Object> keyMap = initKey (); // Build key
 PublicKey publicKey = (PublicKey) keyMap.get (PUBLIC_KEY);
 PrivateKey privateKey = (PrivateKey) keyMap.get (PRIVATE_KEY);
 System.out.println ("Private key format:" + privateKey.getFormat ());
 System.out.println ("Public key format:" + publicKey.getFormat ());
  
  
 // Generate signature
 String sign = sign (data, getPrivateKey (keyMap));
  
 // verify signature
 boolean verify1 = verify ("aaa" .getBytes (), getPublicKey (keyMap), sign);
 System.err.println ("Verified data and signature match:" + verify1);
  
 boolean verify = verify (data, getPublicKey (keyMap), sign);
 System.err.println ("Verified data and signature match:" + verify);
 }
 
 / **
 * Generate key
 *
 * @param seed
 * @return key object
 * @throws Exception
 * /
 public static Map <String, Object> initKey (String seed) throws Exception {
 System.out.println ("Generate key");
  
 KeyPairGenerator keygen = KeyPairGenerator.getInstance (KEY_ALGORITHM);
 SecureRandom secureRandom = new SecureRandom ();
 secureRandom.setSeed (seed.getBytes ());
 // Modulus size must range from 512 to 1024 and be a multiple of 64
 keygen.initialize (640, secureRandom);
  
 KeyPair keys = keygen.genKeyPair ();
 PrivateKey privateKey = keys.getPrivate ();
 PublicKey publicKey = keys.getPublic ();
  
 Map <String, Object> map = new HashMap <String, Object> (2);
 map.put (PUBLIC_KEY, publicKey);
 map.put (PRIVATE_KEY, privateKey);
 return map;
 }
 
 / **
 * Generate default key
 *
 * @return key object
 * @throws Exception
 * /
 public static Map <String, Object> initKey () throws Exception {
 return initKey (DEFAULT_SEED);
 }
 
 / **
 * Get private key
 *
 * @param keyMap
 * @return
 * @throws Exception
 * /
 public static String getPrivateKey (Map <String, Object> keyMap) throws Exception {
 Key key = (Key) keyMap.get (PRIVATE_KEY);
 return encryptBASE64 (key.getEncoded ()); // base64 encrypted private key
 }
 
 / **
 * Get public key
 *
 * @param keyMap
 * @return
 * @throws Exception
 * /
 public static String getPublicKey (Map <String, Object> keyMap) throws Exception {
 Key key = (Key) keyMap.get (PUBLIC_KEY);
 return encryptBASE64 (key.getEncoded ()); // base64 encrypted public key
 }
 
 / **
 * Digitally sign information with a private key
 * @param data encrypted data
 * @param privateKey private key-base64 encrypted
 * @return
 * @throws Exception
 * /
 public static String sign (byte [] data, String privateKey) throws Exception {
 System.out.println ("Digitally sign information with a private key");
  
 byte [] keyBytes = decryptBASE64 (privateKey);
 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec (keyBytes);
 KeyFactory factory = KeyFactory.getInstance (KEY_ALGORITHM);
 PrivateKey priKey = factory.generatePrivate (keySpec); // Generate private key
  
 // Digitally sign information with a private key
 Signature signature = Signature.getInstance (SIGNATURE_ALGORITHM);
 signature.initSign (priKey);
 signature.update (data);
 return encryptBASE64 (signature.sign ());
 }
 
 / **
 * BASE64Encoder encryption
 * @param data The data to be encrypted
 * @return encrypted string
 * /
 private static String encryptBASE64 (byte [] data) {
 BASE64Encoder encoder = new BASE64Encoder ();
 String encode = encoder.encode (data);
 return encode;
 }
 
 / **
 * BASE64Decoder decryption
 * @param data the string to decrypt
 * @return decrypted byte []
 * @throws Exception
 * /
 private static byte [] decryptBASE64 (String data) throws Exception {
 BASE64Decoder decoder = new BASE64Decoder ();
 byte [] buffer = decoder.decodeBuffer (data);
 return buffer;
 }
 
 / **
 * Verify digital signature
 * @param data encrypted data
 * @param publicKey
 * @param sign digital signature
 * @return
 * @throws Exception
 * /
 public static boolean verify (byte [] data, String publicKey, String sign) throws Exception {
 byte [] keyBytes = decryptBASE64 (publicKey);
 X509EncodedKeySpec keySpec = new X509EncodedKeySpec (keyBytes);
 KeyFactory keyFactory = KeyFactory.getInstance (KEY_ALGORITHM);
  PublicKey pubKey = keyFactory.generatePublic (keySpec);
  
  Signature signature = Signature.getInstance (SIGNATURE_ALGORITHM);
  signature.initVerify (pubKey);
  signature.update (data);
  
  return signature.verify (decryptBASE64 (sign)); // verify signature
  }
 
}


Related Article

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.