RAS非对称加解密-RAS加解密和签名和验签,密钥生成器(java代码)

发布时间 2023-09-25 23:03:51作者: oktokeep

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);
    }
}