Common digital signature algorithms RSA and DSA Java program implementation examples

  • 2020-05-07 19:52:09
  • OfStack

RSA encryption algorithm
let's review the encryption algorithm of RSA in 1. Starting from the definition of public key encryption algorithm and signature algorithm, we describe the 1 algorithm in a relatively standard language.
RSA public-key cryptography consists of three algorithms: KeyGen (key generation algorithm), Encrypt (encryption algorithm), and Decrypt (decryption algorithm).
The key generation algorithm takes the security constant as the input and outputs 1 public key PK and 1 private key SK. The security constant is used to determine how secure the encryption algorithm is, 1 generally depending on the size of the prime number p used by the encryption algorithm. The larger the number, the larger the prime number p1, the higher the security of the system. In RSA, the key generation algorithm is as follows: the algorithm first generates two different large prime Numbers p and q randomly, and calculates N=pq. Then the algorithm computes the euler function. Next, the algorithm randomly selects an integer e that is smaller than e, and computes the modular inverse element d of e. Finally, the public key is PK=(N, e), and the private key is SK= (N, d).
The encryption algorithm takes the public key PK and the message M to be encrypted as input and outputs the ciphertext CT. In RSA, the encryption algorithm is as follows: the algorithm directly outputs the ciphertext as
The decryption algorithm takes the private key SK and the ciphertext CT as input and outputs the message M. In RSA, the decryption algorithm is as follows: the algorithm directly outputs the plaintext as. Since e and d are inverses at the bottom, we have:
Therefore, we can also see from the algorithm description that the public key is used to encrypt the data, and the private key is used to decrypt the data. Of course, this also makes intuitive sense: the public key is the public key, and you can use it to encrypt data if it's public. The private key is the private key, who has this key can decrypt the ciphertext. Otherwise, if everyone can see the private key, they can decrypt it.
Let's take a look at 1 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"; // Can't use  
 public static final String CIPHER_ALGORITHM_ECB3 = "OAEPWithSHA-256AndMGF1Padding"; // Can't use  
 
 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);// Private key to decrypt the  
 byte[] decrypt = cipher.doFinal(encrypt); 
 System.out.println(" After the private key is decrypted 1 : " + new String(decrypt)); 
 } 
 
 /** 
 *  The private key is encrypted and the public key is decrypted   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); // The private key encryption  
 byte[] encrypt = cipher.doFinal(str.getBytes()); 
 System.out.println(" After the private key is encrypted 2 : " + Arrays.toString(encrypt)); 
  
 cipher.init(Cipher.DECRYPT_MODE, publicKey);// A public key to decrypt  
 byte[] decrypt = cipher.doFinal(encrypt); 
 System.out.println(" Public key decrypted 2 : " + new String(decrypt)); 
 } 
 
 /** 
 *  The private key is encrypted and the public key is decrypted   use 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); // The private key encryption  
 byte[] encrypt = cipher.doFinal(str.getBytes()); 
 System.out.println(" After the private key is encrypted 3 : " + Arrays.toString(encrypt)); 
  
 cipher.init(Cipher.DECRYPT_MODE, publicKey);// A public key to decrypt  
 byte[] decrypt = cipher.doFinal(encrypt); 
 System.out.println(" Public key decrypted 3 : " + new String(decrypt)); 
 } 
} 

DSA algorithm and digital signature
DSA 1 is commonly used for digital signatures and authentication.
DSA is a variant of Schnorr and ElGamal signature algorithms, and is used by NIST as DSS (DigitalSignature Standard).
DSA is based on the discrete logarithm problem of integer finite field, and its security is similar to RSA.
In DSA digital signature and authentication, the sender signs the file or message using his private key, and the receiver receives the message using the sender's public key
To verify the authenticity of the signature. DSA is just one algorithm. Unlike RSA, it cannot be used for encryption and decryption, and it cannot be used for key exchange.
For signature only, 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 Schnorr and ElGamal A variant of the signature algorithm, by the United States NIST As a DSS(DigitalSignature Standard) .  
 *  In short, this is 1 A more advanced verification method used as a digital signature. Not only the public key, the private key, but also the digital signature. Private key encryption generates digital signature, public key verification data and signature.  
 *  If the data and signature do not match, the validation fails! namely   Data in transit   Can no longer encrypt, after receiving the data, get the public key and signature   Verify that the data is valid  
 */ 
public class DSA { 
 /**
 * Not only can you use DSA The algorithm, again, can be used RSA Algorithms do digital signatures 
 */ 
 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"; // The 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 Dang military road loves you *()_+"; 
 byte[] data = str.getBytes(); 
  
 Map<String, Object> keyMap = initKey();//  Construction of the key  
 PublicKey publicKey = (PublicKey) keyMap.get(PUBLIC_KEY); 
 PrivateKey privateKey = (PrivateKey) keyMap.get(PRIVATE_KEY); 
 System.out.println(" The private key format : " + privateKey.getFormat()); 
 System.out.println(" The public key format : " + publicKey.getFormat()); 
  
  
 //  Generate the signature  
 String sign = sign(data, getPrivateKey(keyMap)); 
  
 //  Verify the 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 the key  
 * 
 * @param seed  seeds  
 * @return  The key object  
 * @throws Exception 
 */ 
 public static Map<String, Object> initKey(String seed) throws Exception { 
 System.out.println(" Generate the 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  The key object  
 * @throws Exception 
 */ 
 public static Map<String, Object> initKey() throws Exception { 
 return initKey(DEFAULT_SEED); 
 } 
 
 /** 
 *  Get the 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 Encryption private key  
 } 
 
 /** 
 *  In 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 Encryption, public key  
 } 
 
 /** 
 *  The information is digitally signed with the private key  
 * @param data  Encrypt the data  
 * @param privateKey  The private key -base64 encrypted  
 * @return 
 * @throws Exception 
 */ 
 public static String sign(byte[] data, String privateKey) throws Exception { 
 System.out.println(" The information is digitally signed with the private key "); 
  
 byte[] keyBytes = decryptBASE64(privateKey); 
 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); 
 KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM); 
 PrivateKey priKey = factory.generatePrivate(keySpec);// generate   The private key  
  
 // The information is digitally signed with the 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  The 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; 
 } 
 
 /** 
 *  Check digital signature  
 * @param data  Encrypt the data  
 * @param publicKey 
 * @param sign  A 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 the signature  
 } 
 
} 


Related articles: