用Java实现RSA加解密及签名和验签(2)——.pfx文件格式秘钥
注:.pfx 主要用于windows平台,浏览器可以使用,也是包含证书和私钥,获取私钥需要密码才可以
.pfx文件生成的方式可参考:https://www.cnblogs.com/ouyanxia/p/12427955.html
1、准备好pfx秘钥文件(alias默认是1)
path=/RSA/other/openssl.pfx pwd=秘钥的秘钥(生成秘钥时记得存好) alias=1 cerPath=/RSA/other/openssl.cer
2、编写RSAUtil
import java.io.FileInputStream; import java.security.Key; import java.security.KeyPair; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import javax.crypto.Cipher; import org.apache.tomcat.util.codec.binary.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class RSAUtil { public static RSAPublicKey publicKey; public static RSAPublicKey tlPublicKey; public static RSAPrivateKey privateKey; public static void configure(RSAConfig config) { try { RSAUtil.publicKey = (RSAPublicKey) loadPublicKey(config.getCerPath()); RSAUtil.privateKey = (RSAPrivateKey) loadPrivateKey(config.getAlias(), config.getPath(), config.getPwd()); } catch (Exception e) { e.printStackTrace(); } } /** * 私钥 * * @param source * @return */ public static String doSignBySHA1withRSA(String source) { byte[] sourceData = source.getBytes(); String result = null; try { // 获得私钥并签名 Signature sign = Signature.getInstance("SHA1WithRSA", new BouncyCastleProvider()); sign.initSign(privateKey); sign.update(sourceData); byte[] resultData = sign.sign(); result = Base64.encodeBase64String(resultData); } catch (Exception e) { e.printStackTrace(); } return result; } public static PrivateKey loadPrivateKey(String alias, String path, String pwd) { PrivateKey privateKey = null; try { // 获得公钥 KeyPair keyPair = null; KeyStore keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(new FileInputStream(path), pwd.toCharArray()); Key key = keyStore.getKey(alias, pwd.toCharArray()); if (key instanceof PrivateKey) { Certificate cert = keyStore.getCertificate(alias); keyPair = new KeyPair(cert.getPublicKey(), (PrivateKey) key); } privateKey = keyPair.getPrivate(); } catch (Exception e) { e.printStackTrace(); } return privateKey; } public static PublicKey loadPublicKey(String cerPath) { PublicKey publicKey = null; try { // 获得公钥 CertificateFactory cf = CertificateFactory.getInstance("X.509"); FileInputStream in = new FileInputStream(cerPath); // 生成一个证书对象并使用从输入流 inStream 中读取的数据对它进行初始化。 Certificate c = cf.generateCertificate(in); publicKey = c.getPublicKey(); } catch (Exception e) { e.printStackTrace(); } return publicKey; } /** * 公钥验签 * * @param sign * @param source * @return */ public static boolean doVerifyBySHA1withRSA(String sign, String source) { boolean result = false; try { // 获得公钥 byte[] sourceData = source.getBytes(); Signature verify = Signature.getInstance("SHA1withRSA"); verify.initVerify(publicKey); verify.update(sourceData); byte[] decoded = Base64.decodeBase64(sign); result = verify.verify(decoded); } catch (Exception e) { e.printStackTrace(); } return result; } /** * 公钥加密 * * @param plainText * @param pkcs8_rsa_public_key * @return */ public static String doEncryptByRSA(String plainText) { byte[] sourceData = plainText.getBytes(); String result = null; try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] resultData = cipher.doFinal(sourceData); result = Base64.encodeBase64String(resultData); } catch (Exception e) { e.printStackTrace(); } return result; } public static String doDecryptByRSA(String encryptedText) { byte[] sourceData = Base64.decodeBase64(encryptedText); String result = null; try { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] resultData = cipher.doFinal(sourceData); result = new String(resultData); } catch (Exception e) { e.printStackTrace(); } return result; } }
3、编写配置类(方便配置)
public class RSAConfig { private String pwd; private String alias; private String path; private String cerPath; public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public String getAlias() { return alias; } public void setAlias(String alias) { this.alias = alias; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getCerPath() { return cerPath; } public void setCerPath(String cerPath) { this.cerPath = cerPath; } public RSAConfig(String pwd, String alias, String path, String cerPath) { super(); this.pwd = pwd; this.alias = alias; this.path = path; this.cerPath = cerPath; } }
4、main方法测试
import com.example.demo.constants.Constants; import com.gworld.rsautil.pfx.RSAConfig; import com.gworld.rsautil.pfx.RSAUtil; public class DemoTest { public static void main(String[] args) throws Exception { RSAConfig config = new RSAConfig(Constants.PWD, Constants.ALIAS, Constants.PFX_PATH, Constants.CER_PATH);//读取配置文件的秘钥配置 RSAUtil.configure(config); String id = "123456789"; String encodeId = RSAUtil.doEncryptByRSA(id); String decodeId = RSAUtil.doDecryptByRSA(encodeId); System.out.println("encodeId="+encodeId); System.out.println("decodeId="+decodeId); String sign = RSAUtil.doSignBySHA1withRSA(id); System.out.println(sign); boolean verify = RSAUtil.doVerifyBySHA1withRSA(sign, id); System.out.println("verify result="+verify); } }
测试结果:
encodeId=Tv4/lRio3ldjfdk/KsiM18tlUMTe+u5i2ZLot3A8TW3bnP8iZgTArC9cxHcbYkTk37/07gOyHWHwpYkjYZ8xNA2d/Fgnf+Z4F23ULO2UgDR00eyjXe7R2XTQgMhSHenQxmaICU45PDs4+esrehSPkyyWB8rTDbB/dwn+wucKmXM= decodeId=123456789 g495zEj7o4PxdRA7SYhGALR04qoLUbznknUrGWm5/AIwYYnt8hym94i/dSAQEJo7jXHbmEZo2N0l4p8BDBIJ7Wp5CIqG2+NXr+aT/QA9MLnOFvpAJ/HzOn+HNzMSOpRNvFZ8Bj12it/cdTGq++qFwrf4uUuzB63V67mjIRVDZrg= verify result=true