RSA encryption and decryption and digital signature Java implementation

The RSA public key encryption algorithm was proposed in 1977 by Ron Rivest, Adi Shamir and Leonard Adleman. All three of them were working at MIT at the time. RSA is the combination of the first letters of their surnames.
    RSA is currently the most influential public key encryption algorithm. It can resist the vast majority of cryptographic attacks known so far and has been recommended by ISO as a public key data encryption algorithm.
    The RSA algorithm is an asymmetric cryptographic algorithm. The so-called asymmetry means that the algorithm requires a pair of keys. If one is used to encrypt, the other needs to be used to decrypt.
    Regarding the principle of the RSA algorithm, I will not introduce it in detail here. There are a lot of various resources on the Internet. Let's start to introduce the specific implementation of RSA encryption and decryption JAVA class.
import java.security.MessageDigest;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class Coder {

public static final String KEY_SHA="SHA";
public static final String KEY_MD5="MD5";

/**
* BASE64 decrypt
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptBASE64(String key) throws Exception{
return (new BASE64Decoder()).decodeBuffer(key);
}

/**
* BASE64加密
* @param key
* @return
* @throws Exception
*/
public static String encryptBASE64(byte[] key)throws Exception{
return (new BASE64Encoder()).encodeBuffer(key);
}

/**
* MD5加密
* @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();
}
}
     First provide the Coder encoding class, which encapsulates the basic Base64, md5 and SHA encryption and decryption algorithms. Java provides a good API encapsulation for the implementation of these algorithms, and developers only need to call these APIs to easily and conveniently implement data encryption and decryption.
    The RSA encryption and decryption class is provided below, which is a subclass of the Coder class, because a layer of Base64 encryption is performed on the storage of the RSA public and private keys.
    RSA encryption and decryption class static constant
       public static final String KEY_ALGORTHM="RSA";//
public static final String SIGNATURE_ALGORITHM="MD5withRSA";

public static final String PUBLIC_KEY = "RSAPublicKey";//public key
public static final String PRIVATE_KEY = "RSAPrivateKey";//


    The implementation of private key RSA encryption and decryption requires a pair of public and private keys. The initialization of the public and private keys is as follows:
/**
* Initialization key
* @return
* @throws Exception
*/
public static Map<String,Object> initKey() throws Exception{
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORTHM);
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();

//public key
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
//private key
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

Map<String,Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);

return keyMap;
}
      It can be seen from the code that the initialization length of the key is 1024 bits. The longer the key length, the better the security, but the longer the encryption and decryption time will be. many. The length of the ciphertext that can be encrypted at one time is also proportional to the length of the key. The length of the ciphertext that can be encrypted at one time is: the length of the key/8-11. Therefore, the ciphertext that can be encrypted by a key with a length of 1024bit at a time is 1024/8-11=117bit. Therefore, asymmetric encryption is generally used to encrypt the key of the symmetric encryption algorithm, rather than directly encrypting the content. RSA encryption can be used for small files, but the encryption process may still use segment encryption.
    Get public key and private key from map
/**
* Get public key and convert to String type
* @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());    
}

/**
* Get the private key and convert it to String type
* @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());    
}

    for RSA generated Public key and private key, we can encrypt and decrypt information in two ways. Private Key Encryption - Public Key Decryption and Public Key Encryption - Private Key Decryption.

    Private key encryption
/**
* Encrypt with private key
* @param data encrypted data
* @param key key
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data,String key)throws Exception{
//Decryption key
byte[] keyBytes = decryptBASE64(key);
//Get private key
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

//Encrypt data
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);

return cipher.doFinal(data);
}
    private key decrypt
/**
* decrypt with private key * @param data encrypted data
* @param key key
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[ ] data,String key)throws Exception{
//Decrypt the private key
byte[] keyBytes = decryptBASE64(key);

PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
//Decrypt data
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);

return cipher.doFinal(data);
}
    public key encryption
/**
* Encrypt with public key
* @param data encrypted data
* @param key key
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[ ] data,String key)throws Exception{
//Decrypt the public key
byte[] keyBytes = decryptBASE64(key);
//Get the public key
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

//Decrypt data
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher. init(Cipher.ENCRYPT_MODE, publicKey);

return cipher.doFinal(data);
}
    private key encryption
/**
* decrypt with public key
* @param data encrypted data
* @param key key
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] data,String key)throws Exception{
//Decrypt the private key
byte[] keyBytes = decryptBASE64(key);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

//Decrypt data
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher. init(Cipher.DECRYPT_MODE, publicKey);

return cipher.doFinal(data);
}
    Regarding digital signatures, first understand what digital signatures are. A digital signature is a digital string that can only be generated by the sender of the information and cannot be forged by others. This digital string is also an effective proof of the authenticity of the information sent by the sender of the information. Digital signature is the application of asymmetric key encryption technology and digital digest technology. Simply put, the so-called digital signature is some data attached to the data unit, or the cryptographic transformation of the data unit. This data or transformation allows the recipient of the data unit to confirm the origin of the data unit and the integrity of the data unit and to protect the data from forgery by a person (eg the recipient).
    The main functions of digital signatures are as follows:

    to ensure the integrity of information transmission, to authenticate the sender, and to prevent denials in transactions.
    Digital signature technology encrypts the digest information with the sender's private key and transmits it to the receiver together with the original text. The receiver can decrypt the encrypted digest message only with the sender's public key, and then generate a digest message from the received original text and compare it with the decrypted digest message. If they are the same, it means that the received information is complete and has not been modified during the transmission process; otherwise, it means that the information has been modified, so the digital signature can verify the integrity of the information.
    Digital signature is an encryption process, and digital signature verification is a decryption process.
     Digital signature algorithms rely on public key encryption technology to achieve. In public key cryptography, each user has a pair of keys: a public key and a private key. The public key can be released freely, but the private key is kept secret; there is also a requirement to make it impossible to deduce the private key from the public key.
    Common digital signature algorithms include three algorithms:
    1. Password generation algorithm;
    2. Marking algorithm;
   3. Verification algorithm.
    Through RSA encryption and decryption algorithm, we can realize the function of digital signature. We can use the private key to generate a digital signature for the information, and then use the public key to verify the digital signature. Of course, we can also reverse the public key signature and the private key verification.
    Private key signature

/**
* Use the private key to generate a digital signature for information
* @param data //encrypted data
* @param privateKey //private key
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception{
//Decrypt private key
byte[] keyBytes = decryptBASE64(privateKey);
//Construct PKCS8EncodedKeySpec object
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
//Specify encryption algorithm
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
//Private key object
PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
//Generate digital signature for information with private key
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateKey2);
signature.update(data);

return encryptBASE64(signature.sign ());
}
    public key verification

/**
* digital signature verification
* @param data encrypted data
* @param publicKey public key
* @param sign digital signature
* @return
* @throws Exception
*/
public static boolean verify(byte[] data,String publicKey,String sign)throws Exception{
// decrypt public key
byte[] keyBytes = decryptBASE64(publicKey);
/ /Construct X509EncodedKeySpec object
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
//Specify encryption algorithm
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
//Get public key object
PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);

Signature signature = Signature.getInstance (SIGNATURE_ALGORITHM);
signature.initVerify(publicKey2);
signature.update(data);
//Verify whether the signature is normal
return signature.verify(decryptBASE64(sign));

}
       For how RSA encrypts files, pictures and other information, how to save the encrypted information, how to save the decrypted information, and how to deal with errors encountered during the operation, will be in the It will be introduced to you in the following article.

  
Share a spring cloud video
Follow the official account to reply to springcloud to get the



original address: https://my.oschina.net/jiangli0502/blog/171263

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326325714&siteId=291194637