使用RSA私钥或pfx私钥签名String

项目有个需求,使用私钥签名请求body内容,放在请求头部,作为头部一个字段内容请求外部服务,签名有二种方式,对方提供私钥串/直接提供pfx私钥文件。

一. 提供私钥串  示例代码如下:

public static void main(String[] args) {
       String key2 = "MII***=="  //使用自己的私钥替换
        try {
            byte[] data = "test".getBytes("UTF8");
            Signature sig = Signature.getInstance("MD5withRSA");//SHA1WithRSA  签名算法
            sig.initSign(readRSAPrivateKey(key2));
            sig.update(data);
            byte[] signatureBytes = sig.sign();
            System.out.println("Signature:" + new BASE64Encoder().encode(signatureBytes));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String signContent(String content) throws Exception{
        byte[] data = content.getBytes("UTF8");
        Signature sig = Signature.getInstance("MD5withRSA");
        sig.initSign(readRSAPrivateKey(key2));
        sig.update(data);
        byte[] signatureBytes = sig.sign();
        return new String(java.util.Base64.getEncoder().encode(signatureBytes)); //new BASE64Encoder().encode(signatureBytes); 
  }

public static PrivateKey readRSAPrivateKey(String privateKey) throws NoSuchAlgorithmException, IOException, InvalidKeySpecException { byte[] keyBytes = java.util.Base64.getDecoder().decode(privateKey.getBytes());
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); 
KeyFactory kf
= KeyFactory.getInstance("RSA");
PrivateKey key
= kf.generatePrivate(spec);

return key; }

如果需要公钥解码,结合私钥签名,代码如下

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;

import sun.misc.BASE64Encoder;

public class MainClass {
    public static void main(String[] args) throws Exception {

        KeyPair keyPair = getKeyPair();

        byte[] data = "test".getBytes("UTF8");

        Signature sig = Signature.getInstance("SHA1WithRSA");
        sig.initSign(keyPair.getPrivate());
        sig.update(data);
        byte[] signatureBytes = sig.sign();
        System.out.println("Signature:" + new BASE64Encoder().encode(signatureBytes));

        sig.initVerify(keyPair.getPublic());
        sig.update(data);

        System.out.println(sig.verify(signatureBytes));
    }

    private static KeyPair getKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024);
        return kpg.genKeyPair();
    }
}

二. 如果别人提供给你的是pfx文件,你可以选择把peivate key提取出来,或者直接使用pfx文件签名也可以。

1. 提取的命令:openssl pkcs12 -in test-private.pfx -nocerts -nodes -out key2.pem

 如果需要的是老格式的:openssl pkcs8 -in key.pem -out rsakey.pem

2. 直接使用pfx文件签名String代码如下

/**
     * @param algorithm  签名算法: SHA1WithRSA / MD5withRSA等
     * @param password 密码
     * @param privateKeyPath pfx文件路径
     * @throws Exception
     */
    public RSASignUtils(String algorithm, String password, String privateKeyPath) throws Exception {
        this.algorithm = algorithm;
        this.password = password;

        try{
            KeyStore ks = KeyStore.getInstance("PKCS12");
            InputStream fis = RSASignUtils.class.getResourceAsStream(privateKeyPath);
            char[] nPassword = null;
            if ((password == null) || password.trim().equals("")) {
                nPassword = null;
            } else {
                nPassword = password.toCharArray();
            }
            ks.load(fis, nPassword);
            fis.close();
            Enumeration enuml = ks.aliases();
            String keyAlias = null;
            if (enuml.hasMoreElements()) {
                keyAlias = (String) enuml.nextElement();
                logger.info("RSASignUtils alias=[" + keyAlias + "]");
            }
            logger.info("RSASignUtils is key entry = " + ks.isKeyEntry(keyAlias));
            PrivateKey prikey = (PrivateKey) ks.getKey(keyAlias, nPassword);
            logger.info("RSASignUtils keystore type = " + ks.getType());
            signature = Signature.getInstance(algorithm);
            signature.initSign(prikey);

        } catch (Exception e) {
            logger.error(String.format("RSA signature object generate failure...%s", e.getMessage()));
            throw e;
        }

    }

    public String generate(String body) throws UnsupportedEncodingException, SignatureException {

        //Read the string into a buffer
        byte[] dataInBytes = body.getBytes("UTF-8");

        //update signature with data to be signed
        signature.update(dataInBytes);

            //sign the data
        byte[] signedInfo = signature.sign();

        return Base64.getEncoder().encodeToString(signedInfo);//Base64.encode(signedInfo);
    }
欢迎关注Java流水账公众号
原文地址:https://www.cnblogs.com/guofu-angela/p/10905180.html