使用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流水账公众号