RAS非对称加解密-RAS加解密和签名和验签,密钥生成器(java代码)
RAS非对称加解密-RAS加解密和签名和验签,密钥生成器(java代码)
RSA 算法是一种非对称加解密算法。服务方生成一对 RSA 密钥,即公钥 + 私钥,将公钥提供给调用方,调用方使用公钥对数据进行加密后,服务方根据私钥进行解密。
1. RAS密钥生成器
2. RAS加解密和签名和验签 代码1
3. RAS实现签名和验签 代码2
import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; /** * 密钥生成器 */ public class RSAKeysGenerator { /** * RsaKey 密钥生成器 * * @return stirng[0]-pubKey string[1]-privKey * @throws Exception * @author guolei */ public static String[] generateRsaKeys() throws Exception { String[] keys = new String[2]; String pubKeyStr = "", priKeyStr = ""; KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); generator.initialize(1024);// 1024 bit KeyPair pair = generator.generateKeyPair(); PublicKey pubKey = pair.getPublic(); PrivateKey privKey = pair.getPrivate(); pubKeyStr = Base64.encode(pubKey.getEncoded()).replaceAll(" ", ""); priKeyStr = Base64.encode(privKey.getEncoded()).replaceAll(" ", ""); keys[0] = pubKeyStr; // public Key keys[1] = priKeyStr; // private key return keys; } public static void main(String[] args) { try { String[] keys = generateRsaKeys(); System.out.println("Public Key::" + keys[0]); System.out.println("Private Key::" + keys[1]); } catch (Exception e) { e.printStackTrace(); } } }
2. RAS加解密和签名和验签 代码1
import javax.crypto.Cipher; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; public class RSA { public static final String SIGN_ALGORITHMS = "SHA1WithRSA"; /** * RSA签名 * @param content 待签名数据 * @param privateKey 商户私钥 * @param input_charset 编码格式 * @return 签名值 */ public static String sign(String content, String privateKey, String input_charset) { try { PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64.decode(privateKey) ); KeyFactory keyf = KeyFactory.getInstance("RSA"); PrivateKey priKey = keyf.generatePrivate(priPKCS8); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initSign(priKey); signature.update( content.getBytes(input_charset) ); byte[] signed = signature.sign(); return Base64.encode(signed); } catch (Exception e) { e.printStackTrace(); } return null; } /** * RSA验签名检查 * @param content 待签名数据 * @param sign 签名值 * @param ali_public_key 支付宝公钥 * @param input_charset 编码格式 * @return 布尔值 */ public static boolean verify(String content, String sign, String ali_public_key, String input_charset) { try { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] encodedKey = Base64.decode(ali_public_key); PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initVerify(pubKey); signature.update( content.getBytes(input_charset) ); boolean bverify = signature.verify( Base64.decode(sign) ); return bverify; } catch (Exception e) { e.printStackTrace(); } return false; } /** * 私钥解密 * @param content 密文 * @param private_key 商户私钥 * @param input_charset 编码格式 * @return 解密后的字符串 */ public static String decrypt(String content, String private_key, String input_charset) throws Exception { PrivateKey prikey = getPrivateKey(private_key); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, prikey); InputStream ins = new ByteArrayInputStream(Base64.decode(content)); ByteArrayOutputStream writer = new ByteArrayOutputStream(); //rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密 byte[] buf = new byte[128]; int bufl; while ((bufl = ins.read(buf)) != -1) { byte[] block = null; if (buf.length == bufl) { block = buf; } else { block = new byte[bufl]; for (int i = 0; i < bufl; i++) { block[i] = buf[i]; } } writer.write(cipher.doFinal(block)); } return new String(writer.toByteArray(), input_charset); } /** * 私钥解密 * * @param secretText 待解密的密文字符串 * @param privateKeyStr 私钥 * @return 解密后的明文 */ public static String decrypt1(String secretText, String privateKeyStr,String input_charset) { try { // 生成私钥 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKeyStr)); // 密文解码 byte[] secretTextDecoded = Base64.decode(secretText); byte[] tempBytes = cipher.doFinal(secretTextDecoded); return new String(tempBytes); } catch (Exception e) { throw new RuntimeException("解密字符串[" + secretText + "]时遇到异常", e); } } /** * 公钥 加密 * @param content * @param * @param input_charset * @return * @throws Exception */ public static String encrypt(String content, String public_key, String input_charset) throws Exception { PublicKey pubkey = getPublicKey(public_key); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubkey); byte[] tempBytes = cipher.doFinal(content.getBytes("UTF-8")); return Base64.encode(tempBytes); // return new String(tempBytes, input_charset); } /** * 得到私钥 * @param key 密钥字符串(经过base64编码) * @throws Exception */ private static PrivateKey getPrivateKey(String key) throws Exception { byte[] keyBytes; keyBytes = Base64.decode(key); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } /** * 得到公钥 * @param key * @return * @throws Exception */ private static PublicKey getPublicKey(String key) throws Exception { byte[] keyBytes; keyBytes = Base64.decode(key); //Only RSAPublicKeySpec and X509EncodedKeySpec supported for RSA public keys // PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; } /** * 报文体签名=f6G0o2wme/8uiQFt6/FRd0kO160Mp+NEs9p3JizqHY3SjqYdp28Bk+DJW4heYLrmSIt3PyHrOdKGRppqfdjJt02VXUJyc/A0Xg0KuQ3ulfpmqzxOA4gzNea+CeZtLUjzshXq2WedEgH4QF4LrFkDeaMWefE3YkIOfwcbNrcJJtE= * verify flag=true * enctyptString=g0XdRF6wAELkudaOCdolTBhx4mkSX/7LtvbMKd1AZt79H2MSKI7U+fvR4Sb6NL8028LlH9lmmS3Og7BKzNz+yBhvGOiA3NKlIMh1GTBNsfmPwXapFcVDFghbkc/cpWyOLHv263fSHxCN4cVYenQYAxOSQgK2VZ7bMtt8E87eZSg= * detyptString={amount=250, name=张三, orderId=2014061114360001} * detyptStringNew={amount=250, name=张三, orderId=2014061114360001} * * @param args */ public static void main(String[] args) { String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUDWMv2wCwYlFKJebtYc+E3rji8rnYEeRZGU9t4Y6RFAhJfsCm1yUGAS26PhAsgYTJIptnBESr+RtATxOelh03JwEyFXEYyZyl2VQnbtAftHkkcnLp812z4FyDPRldwVj1AAdFGUEhYW4Hc1sbRJnv41LNJBDio8jiKPGQT9titQIDAQAB"; String priKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJQNYy/bALBiUUol5u1hz4TeuOLyudgR5FkZT23hjpEUCEl+wKbXJQYBLbo+ECyBhMkim2cERKv5G0BPE56WHTcnATIVcRjJnKXZVCdu0B+0eSRycunzXbPgXIM9GV3BWPUAB0UZQSFhbgdzWxtEme/jUs0kEOKjyOIo8ZBP22K1AgMBAAECgYBMmIiCT7mRh6wqwmUw1vO3+EqLD6zafpc3CYMwhAtwP37yFyOwrYo4CxAPVOClRfTe4oqnx2uH1X8lzEOIPn2qJFU1AQdiC9XmvLkqeoa1jXH2rwDwxbs8VYE/1wEzFa/u7dAYu+0lnokgPx03cdZEA5AiQq26fQ0yFoipCHJhAQJBAP5MOI5G1FsXhIXZWFup+7ZkoHVuqoHxafV5I7RVEXmRdVBHEzbY7Rf7QMWGfS7rEGnLuEKjWNMHgUDZHEkJZ5UCQQCVCxkpcrJW7u+BLL61Rl1X4wuN0Z4HKQPj/YhGD0lnkssKUPW9GCy1dQUp00yvRfCwz0s4rdfGGMWlA1xqhMahAkEAgn3eb7QM+ImC6aR0YOVDU38jj98wA+o780ksdzdH9lgcGQu/4l9CmxHFVRcEWfUpwQBXF2r3A6NQQlSm3RvEWQJAJD3OoIWDWCBBnOeEeA/kIrrS1GlkQ9l1WLsNp/uPnd/T/24wUwrN1FHgL4tx2iznmhbN87pR/ZmIddebYUtoAQJAfAPoHMSLPCqZgVFTo/uQU3Zq2GbGmo1B7cLrnBu62DsUlqoVk31dVLC9inKuRwOsXlp8s3gmadiJlMZJUwf+xQ=="; String content ="{amount=250, name=张三, orderId=2014061114360001}"; //rsa签名和验证签名 //私钥加密 生成报文体和报文体签名 String signData = sign(content,priKey,"UTF-8"); System.out.println("报文体签名="+signData); //公钥验证签名 boolean f = verify(content,signData,pubKey,"UTF-8"); System.out.println("verify flag="+f); try { String enctyptString = encrypt(content,pubKey,"UTF-8"); System.out.println("enctyptString="+enctyptString); //解密的方法1 String detyptString = decrypt(enctyptString,priKey,"UTF-8"); System.out.println("detyptString="+detyptString); //decrypt1 解密的方法2 String detyptStringNew = decrypt1(enctyptString,priKey,"UTF-8"); System.out.println("detyptStringNew="+detyptStringNew); } catch (Exception e) { e.printStackTrace(); } } }
3. RAS实现签名和验签 代码2
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URLDecoder; import java.net.URLEncoder; import java.security.KeyFactory; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; /** * 签名以及验签 */ public class RSAUtil { private static final Logger logger = LoggerFactory.getLogger(RSAUtil.class); /** RSA:加密算法 */ private static final String KEY_ALGORITHM = "RSA"; /** SHA1WithRSA:用SHA算法进行签名,用RSA算法进行加密 */ private static final String SIGN_ALGORITHMS = "SHA1withRSA"; /** * 生成报文体和报文体签名 * * @param privateKey * @param content * @param encoding * @return */ public static String[] signData(String privateKey, String content, String encoding) { logger.info("原始报文内容:" + content); String param[] = new String[2]; try { // 报文体使用base64编码 content = Base64.encode(content.getBytes(encoding)); // 删除base64编码中的空格 content = content.replaceAll(" ", ""); // 生成报文体签名 String contentSign = envolopData(privateKey, content); // 报文体签名进行url编码 contentSign = URLEncoder.encode(contentSign, encoding); logger.info("报文体签名:" + contentSign); // 报文体进行url编码 content = URLEncoder.encode(content, encoding); logger.info("base64编码报文体:" + content); // 返回报文体签名 param[0] = contentSign; // 返回报文体 param[1] = content; } catch (Exception e) { e.printStackTrace(); } return param; } /** * 生成报文体签名 * * @param privateKey * @param content * @return */ private static String envolopData(String privateKey, String content) { // 报文体签名 String contentSign = ""; try { // 根据密钥字符创建密钥类 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey)); KeyFactory fac = KeyFactory.getInstance(KEY_ALGORITHM); RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) fac.generatePrivate(keySpec); // 创建签名算法类 Signature sigEng = Signature.getInstance(SIGN_ALGORITHMS); sigEng.initSign(rsaPrivateKey); // 生成签名 sigEng.update(content.getBytes("UTF-8")); byte[] signature = sigEng.sign(); // base64编码[请求报文签名] contentSign = Base64.encode(signature); // 删除换行符[请求报文签名] contentSign = contentSign.replaceAll(" ", ""); } catch (Exception e) { e.printStackTrace(); } return contentSign; } /** * 验证返回的报文的签名 * @param publicKey 公钥 * @param sign 返回报文体的签名 * @param src 返回报文体 * @param encoding 编码格式 * @return */ public static boolean rsaVerify(String publicKey, String sign, String src, String encoding) { // 验签结果 boolean result = false; try { // url解密[返回报文签名] sign = URLDecoder.decode(sign, encoding); // base64解密[返回报文签名] byte[] signature = Base64.decode(sign); // url解密[返回报文] src = URLDecoder.decode(src, encoding); // 根据密钥创建密钥类 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKey)); KeyFactory fac = KeyFactory.getInstance(KEY_ALGORITHM); RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec); // 创建签名方法类 Signature sigEng = Signature.getInstance(SIGN_ALGORITHMS); sigEng.initVerify(rsaPubKey); // 生成签名 sigEng.update(src.getBytes(encoding)); // 验证签名是一致 result = sigEng.verify(signature); } catch (Exception e) { e.printStackTrace(); } return result; } /** * 解密返回的报文体信息 * * @param content * @param encoding * @return */ public static String decodeContent(String content, String encoding){ String result = ""; try { // 返回报文体的签名执行url解密 result = URLDecoder.decode(content, encoding); // 返回报文体的签名执行base64解密 result = new String(Base64.decode(result), encoding); } catch (Exception e) { e.printStackTrace(); } return result; } /** * 报文体签名=JZqGuYnoNkjre6qsIk5avdfYhkHyXDnxkEaSy9UMygX8cvVn4fvMc8can5rZUSefnI3M6a5RCH2YtHuu3TqVb%2FAIoQ8zNeWXb7OeRWgfbR8KrOGTZdfuZebQwT5Id9HBubLQ4BnnRUoPtgbpVZbHr26RwJMhPg36SYUaHPvA0k0%3D * base64编码报文体=e2Ftb3VudD0yNTAsIG5hbWU95byg5LiJLCBvcmRlcklkPTIwMTQwNjExMTQzNjAwMDF9 * 解析={amount=250, name=张三, orderId=2014061114360001} * verify flag=true * * 报文体签名=f6G0o2wme/8uiQFt6/FRd0kO160Mp+NEs9p3JizqHY3SjqYdp28Bk+DJW4heYLrmSIt3PyHrOdKGRppqfdjJt02VXUJyc/A0Xg0KuQ3ulfpmqzxOA4gzNea+CeZtLUjzshXq2WedEgH4QF4LrFkDeaMWefE3YkIOfwcbNrcJJtE= * verify flag=true * * 测试类 * @param args */ public static void main(String[] args) { String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUDWMv2wCwYlFKJebtYc+E3rji8rnYEeRZGU9t4Y6RFAhJfsCm1yUGAS26PhAsgYTJIptnBESr+RtATxOelh03JwEyFXEYyZyl2VQnbtAftHkkcnLp812z4FyDPRldwVj1AAdFGUEhYW4Hc1sbRJnv41LNJBDio8jiKPGQT9titQIDAQAB"; String priKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJQNYy/bALBiUUol5u1hz4TeuOLyudgR5FkZT23hjpEUCEl+wKbXJQYBLbo+ECyBhMkim2cERKv5G0BPE56WHTcnATIVcRjJnKXZVCdu0B+0eSRycunzXbPgXIM9GV3BWPUAB0UZQSFhbgdzWxtEme/jUs0kEOKjyOIo8ZBP22K1AgMBAAECgYBMmIiCT7mRh6wqwmUw1vO3+EqLD6zafpc3CYMwhAtwP37yFyOwrYo4CxAPVOClRfTe4oqnx2uH1X8lzEOIPn2qJFU1AQdiC9XmvLkqeoa1jXH2rwDwxbs8VYE/1wEzFa/u7dAYu+0lnokgPx03cdZEA5AiQq26fQ0yFoipCHJhAQJBAP5MOI5G1FsXhIXZWFup+7ZkoHVuqoHxafV5I7RVEXmRdVBHEzbY7Rf7QMWGfS7rEGnLuEKjWNMHgUDZHEkJZ5UCQQCVCxkpcrJW7u+BLL61Rl1X4wuN0Z4HKQPj/YhGD0lnkssKUPW9GCy1dQUp00yvRfCwz0s4rdfGGMWlA1xqhMahAkEAgn3eb7QM+ImC6aR0YOVDU38jj98wA+o780ksdzdH9lgcGQu/4l9CmxHFVRcEWfUpwQBXF2r3A6NQQlSm3RvEWQJAJD3OoIWDWCBBnOeEeA/kIrrS1GlkQ9l1WLsNp/uPnd/T/24wUwrN1FHgL4tx2iznmhbN87pR/ZmIddebYUtoAQJAfAPoHMSLPCqZgVFTo/uQU3Zq2GbGmo1B7cLrnBu62DsUlqoVk31dVLC9inKuRwOsXlp8s3gmadiJlMZJUwf+xQ=="; String content ="{amount=250, name=张三, orderId=2014061114360001}"; //私钥加密 生成报文体和报文体签名 String[] signData = signData(priKey,content,"UTF-8"); System.out.println("报文体签名="+signData[0]); System.out.println("base64编码报文体="+signData[1]); //解密返回的报文体信息 System.out.println("解析="+decodeContent(signData[1],"UTF-8")); //公钥验证签名 boolean f = rsaVerify(pubKey,signData[0],signData[1],"UTF-8"); System.out.println("verify flag="+f); } }