java rsa私钥加密是一种加密算法。私钥加密算法是用私钥来进行加密与解密信息。私钥加密也被称作对称加密,原因是加密与解密使用的秘钥是同一个。
RSA加密需要注意的事项如下:
1. 首先产生公钥与私钥
2. 设计加密与解密的算法
3. 私钥加密的数据信息只能由公钥可以解密
4. 公钥加密的数据信息只能由私钥可以解密
实战演练,具体步骤如下: public class RsaCryptTools { private static final String CHARSET = "utf-8" private static final Base64.Decoder decoder64 = Base64.getDecoder() private static final Base64.Encoder encoder64 = Base64.getEncoder() /** * 生成公私钥 * @param keySize * @return * @throws NoSuchAlgorithmException */ public static SecretKey generateSecretKey(int keySize) throws NoSuchAlgorithmException { //生成密钥对 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA") keyGen.initialize(keySize, new SecureRandom()) KeyPair pair = keyGen.generateKeyPair() PrivateKey privateKey = pair.getPrivate() PublicKey publicKey = pair.getPublic() //这里可以将密钥对保存到本地 return new SecretKey(encoder64.encodeToString(publicKey.getEncoded()), encoder64.encodeToString(privateKey.getEncoded())) } /** * 私钥加密 * @param data * @param privateInfoStr * @return * @throws IOException * @throws InvalidCipherTextException */ public static String encryptData(String data, String privateInfoStr) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException { Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding") cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey(privateInfoStr)) return encoder64.encodeToString(cipher.doFinal(data.getBytes(CHARSET))) } /** * 公钥解密 * @param data * @param publicInfoStr * @return */ public static String decryptData(String data, String publicInfoStr) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException { byte[] encryptDataBytes=decoder64.decode(data.getBytes(CHARSET)) //解密 Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding") cipher.init(Cipher.DECRYPT_MODE, getPublicKey(publicInfoStr)) return new String(cipher.doFinal(encryptDataBytes), CHARSET) } private static PublicKey getPublicKey(String base64PublicKey) throws NoSuchAlgorithmException, InvalidKeySpecException { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64PublicKey.getBytes())) KeyFactory keyFactory = KeyFactory.getInstance("RSA") return keyFactory.generatePublic(keySpec) } private static PrivateKey getPrivateKey(String base64PrivateKey) throws NoSuchAlgorithmException, InvalidKeySpecException { PrivateKey privateKey = null PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(base64PrivateKey.getBytes())) KeyFactory keyFactory = null keyFactory = KeyFactory.getInstance("RSA") privateKey = keyFactory.generatePrivate(keySpec) return privateKey } /** * 密钥实体 * @author hank * @since 2020/2/28 0028 下午 16:27 */ public static class SecretKey { /** * 公钥 */ private String publicKey /** * 私钥 */ private String privateKey public SecretKey(String publicKey, String privateKey) { this.publicKey = publicKey this.privateKey = privateKey } public String getPublicKey() { return publicKey } public void setPublicKey(String publicKey) { this.publicKey = publicKey } public String getPrivateKey() { return privateKey } public void setPrivateKey(String privateKey) { this.privateKey = privateKey } @Override public String toString() { return "SecretKey{" + "publicKey='" + publicKey + '\'' + ", privateKey='" + privateKey + '\'' + '}' } } private static void writeToFile(String path, byte[] key) throws IOException { File f = new File(path) f.getParentFile().mkdirs() try(FileOutputStream fos = new FileOutputStream(f)) { fos.write(key) fos.flush() } } public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException { SecretKey secretKey = generateSecretKey(2048) System.out.println(secretKey) String enStr = encryptData("你好测试测试", secretKey.getPrivateKey()) System.out.println(enStr) String deStr = decryptData(enStr, secretKey.getPublicKey()) System.out.println(deStr) enStr = encryptData("你好测试测试hello", secretKey.getPrivateKey()) System.out.println(enStr) deStr = decryptData(enStr, secretKey.getPublicKey()) System.out.println(deStr) } }
代码如下,需要依赖一个jar包commons-codec-1.9.jar,用于Base64转换,请自行下载。
import org.apache.commons.codec.binary.Base64import javax.crypto.BadPaddingException
import javax.crypto.Cipher
import javax.crypto.IllegalBlockSizeException
import java.io.ByteArrayOutputStream
import java.io.UnsupportedEncodingException
import java.security.*
import java.security.interfaces.RSAPrivateKey
import java.security.interfaces.RSAPublicKey
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
public class RSAUtils {
// 加密方式
public static final String ALGORITHM = "RSA"
// 签名算法
private static final String SIGNATURE_ALGORITHM = "SHA1WithRSA"
// 创建密钥对初始长度
private static final int KEY_SIZE = 512
// 字符编码格式
private static final String CHARSET = "UTF-8"
// RSA最大加密明文大小
private static final int MAX_ENCRYPT_BLOCK = 117
// RSA最大解密密文大小
private static final int MAX_DECRYPT_BLOCK = 128
private KeyFactory keyFactory
public RSAUtils() throws NoSuchAlgorithmException {
keyFactory = KeyFactory.getInstance(ALGORITHM)
}
/**
* 私钥加密
*
* @param content 待加密字符串
* @param privateKey 私钥
* @return 加密后字符串(BASE64编码)
*/
public String encryptByPrivateKey(String content, String privateKey) throws Exception {
String result
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] keyBytes = new Base64().decode(privateKey)
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes)
PrivateKey pKey = keyFactory.generatePrivate(pkcs8KeySpec)
Cipher cipher = Cipher.getInstance(ALGORITHM)
cipher.init(Cipher.ENCRYPT_MODE, pKey)
byte[] data = content.getBytes(CHARSET)
write2Stream(cipher, data, out)
byte[] resultBytes = out.toByteArray()
result = Base64.encodeBase64String(resultBytes)
} catch (Exception e) {
throw new Exception(e)
}
return result
}
/**
* 公钥解密
*
* @param content 已加密字符串(BASE64加密)
* @param publicKey 公钥
* @return
*/
public String decryptByPublicKey(String content, String publicKey) throws Exception {
String result = ""
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] keyBytes = new Base64().decode(publicKey)
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes)
PublicKey pKey = keyFactory.generatePublic(x509KeySpec)
Cipher cipher = Cipher.getInstance(ALGORITHM)
cipher.init(Cipher.DECRYPT_MODE, pKey)
byte[] data = Base64.decodeBase64(content)
write2Stream(cipher, data, out)
byte[] resultBytes = out.toByteArray()
result = new String(resultBytes)
} catch (Exception e) {
throw new Exception(e)
}
return result
}
/**
* 公钥加密
*
* @param content 待加密字符串
* @param publicKey 公钥
* @return 加密后字符串(BASE64编码)
*/
public String encryptByPublicKey(String content, String publicKey) throws Exception {
String result = ""
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] keyBytes = new Base64().decode(publicKey)
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes)
PublicKey pKey = keyFactory.generatePublic(x509KeySpec)
Cipher cipher = Cipher.getInstance(ALGORITHM)
cipher.init(Cipher.ENCRYPT_MODE, pKey)
byte[] data = content.getBytes(CHARSET)
write2Stream(cipher,
data, out)
byte[] resultBytes = out.toByteArray()
result = Base64.encodeBase64String(resultBytes)
} catch (Exception e) {
throw new Exception(e)
}
return result
}
/**
* 私钥解密
*
* @param content 已加密字符串
* @param privateKey 私钥
* @return 解密后字符串
*/
public String decryptByPrivateKey(String content, String privateKey) throws Exception {
String result = ""
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] keyBytes = new Base64().decode(privateKey)
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes)
PrivateKey pKey = keyFactory.generatePrivate(pkcs8KeySpec)
Cipher cipher = Cipher.getInstance(ALGORITHM)
cipher.init(Cipher.DECRYPT_MODE, pKey)
byte[] data = Base64.decodeBase64(content)
write2Stream(cipher, data, out)
byte[] resultBytes = out.toByteArray()
result = new String(resultBytes)
} catch (Exception e) {
throw new Exception(e)
}
return result
}
private static void write2Stream(Cipher cipher, byte[] data, ByteArrayOutputStream out) throws
BadPaddingException, IllegalBlockSizeException {
int dataLen = data.length
int offSet = 0
byte[] cache
int i = 0
// 对数据分段解密
while (dataLen - offSet > 0) {
if (dataLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK)
} else {
cache = cipher.doFinal(data, offSet, dataLen - offSet)
}
out.write(cache, 0, cache.length)
i++
offSet = i * MAX_DECRYPT_BLOCK
}
}
/**
* 用私钥对信息生成数字签名
*
* @param data 已加密数据
* @param privateKey 私钥(BASE64编码)
* @return sign
*/
public String sign(String data, String privateKey) throws Exception {
String result = ""
try {
byte[] keyBytes = new Base64().decode(privateKey)
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes)
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec)
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM)
signature.initSign(privateK)
signature.update(parse2HexStr(data).getBytes(CHARSET))
result = new Base64().encodeToString(signature.sign())
} catch (Exception e) {
throw new Exception(e)
}
return result
}
/**
* 校验数字签名
*
* @param data 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param sign 数字签名
* @return
* @throws Exception
*/
public boolean verify(String data, String publicKey, String sign) throws Exception {
boolean result
try {
byte[] keyBytes = new Base64().decode(publicKey)
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes)
PublicKey publicK = keyFactory.generatePublic(keySpec)
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM)
signature.initVerify(publicK)
signature.update(parse2HexStr(data).getBytes(CHARSET))
result = signature.verify(new Base64().decode(sign))
} catch (Exception e) {
throw new Exception(e)
}
return result
}
/**
* 将二进制转换成16进制
*
* @param data
* @return
*/
public static String parse2HexStr(String data) throws Exception {
String result = ""
try {
byte[] buf = data.getBytes(CHARSET)
StringBuffer sb = new StringBuffer()
for (int i = 0 i < buf.length i++) {
String hex = Integer.toHexString(buf[i] & 0xFF)
if (hex.length() == 1) {
hex = '0' + hex
}
sb.append(hex.toUpperCase())
}
result = sb.toString()
} catch (UnsupportedEncodingException e) {
throw new Exception(e)
}
return result
}
/**
* 生成公钥与私钥
*/
public static void createKey() throws Exception {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM)
keyPairGenerator.initialize(KEY_SIZE)
KeyPair keyPair = keyPairGenerator.generateKeyPair()
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic()
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate()
String publicKey = Base64.encodeBase64String(rsaPublicKey.getEncoded())
String privateKey = Base64.encodeBase64String(rsaPrivateKey.getEncoded())
System.out.println("publicKey=" + publicKey + "\nprivateKey=" + privateKey)
} catch (NoSuchAlgorithmException e) {
throw new Exception(e)
}
}
public static void main(String[] args) throws Exception {
String PRIVATE_KEY = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAKeYGXH6Vz+m+KuL11RDRaNdHB4YQeZgqpJGPRSwBelgvEoHu2/fNs1bmgfJhI8lhr/o/Hy8EFB/I/DDyLcCcU4bCLtxpki8edC+KJR2WvyYfnVmWEe/3q2jSVKRf81868q9Cd3MMfrQPMsY4x0TQ0GtOf/nMSMbAltV2W8J86IfAgMBAAECgYEApYu4lr2SMW3ddJZNvQ42W4g9nfyYG9igpJx8+VJmhIDpfLbmjzsOBwvUupx0NHH9CNQ7k3qxItJzzf+W5C+lesEOAqdO5nahRZsL8BIDoxTEn2j+1GXkzQw3vqPY50xqRnZsoP5TyNNsOM7KYaOoz4VFMdVIFwoT3OKM5z7mxgECQQD51r17WZDSa/kucaH7gCOePxJPS6Ust0eVd5tBOMpFzD/VtziogSIWyhGKkLH0SyTJEe91CCpdpxufLSZgIiN5AkEAq7ojtvU4twak1N1/1qX+t8f5wD8i/8GU702PeCwkGI5ymrARq+W2yCuvU1bouXBhjKHV4KhafKYixdHUMg00VwJAYVUjpLaUESY3gbyLWqvlNHVl8LaLtwwAO17JgXNaei7Ef8JNtHf6i95VTyJn8cCEqEDwhSuVNb8wp6azWKh0IQJBAJHrcT2d0bt0IcvfCynRk0eG3WnGPG8mhu9w8GAk4ecb47YdtmZio5YjyK8AQnCQVdOyEJL9eyY/5XxCeBSvs7ECQQCKQ2f5HLDkkHvc6rlaHCJmqNRCS+CxhoaiaSPYLAac7WXmb614ACLECc86C/nkefTq0SNpUDVbGxVpJi9/FOUf"
String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnmBlx+lc/pviri9dUQ0WjXRweGEHmYKqSRj0UsAXpYLxKB7tv3zbNW5oHyYSPJYa/6Px8vBBQfyPww8i3AnFOGwi7caZIvHnQviiUdlr8mH51ZlhHv96to0lSkX/NfOvKvQndzDH60DzLGOMdE0NBrTn/5zEjGwJbVdlvCfOiHwIDAQAB"
RSAUtils rsaUtil = new RSAUtils()
String encryptByPublicKey = rsaUtil.encryptByPublicKey("你好!", PUBLIC_KEY)
System.out.println(encryptByPublicKey)
String decryptByPrivateKey = rsaUtil.decryptByPrivateKey(encryptByPublicKey, PRIVATE_KEY)
System.out.println(decryptByPrivateKey)
String encryptByPrivateKey = rsaUtil.encryptByPrivateKey("你好!", PRIVATE_KEY)
System.out.println(encryptByPrivateKey)
String decryptByPublicKey = rsaUtil.decryptByPublicKey(encryptByPrivateKey, PUBLIC_KEY)
System.out.println(decryptByPublicKey)
String sign = rsaUtil.sign("1234", PRIVATE_KEY)
System.out.println("sign:" + sign)
System.out.println(rsaUtil.verify("1234", PUBLIC_KEY, sign))
}
}