您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關Java讀取OpenSSL實現生成PEM公鑰文件的操作,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
代碼如下:
@Service class SignService { private static Logger LOG = LoggerFactory.getLogger(SignService.class); @Autowired private Config config; private Signature signature; @PostConstruct private void init() { try { PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( getDecoder().decode(config.getPrivateKey().getBytes(ISO_8859_1))); KeyFactory factory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = factory.generatePrivate(priKeySpec); signature = Signature.getInstance("SHA1WithRSA"); signature.initSign(privateKey); } catch (NoSuchAlgorithmException | /*InvalidAlgorithmParameterException |*/ InvalidKeySpecException | InvalidKeyException ex) { LOG.warn("RSA init error: {}.", ex); } } String signAndEncode(String source) { if (Objects.isNull(source)) { return null; } else { return sign(source) .map(this::encode) .orElse(""); } } private String encode(byte[] source) { return getEncoder() .encodeToString(source); } private synchronized Optional<byte[]> sign(String source) { try { signature.update(source.getBytes(ISO_8859_1)); return Optional.of(signature.sign()); } catch (SignatureException e) { LOG.warn("SHA1WithRSA {} error: {}.", source, e); return Optional.empty(); } } }
單元測試,驗證簽名是否正確。先初始化Signature:
private Signature signature; @Before public void init() { try { byte[] key = Files.readAllBytes(Paths.get("/home/ls", "ras_public_key.pem")); Security.addProvider(new BouncyCastleProvider()); final PemObject pemObject; try (PemReader pemReader = new PemReader(new InputStreamReader( new ByteArrayInputStream(key)))) { pemObject = pemReader.readPemObject(); } X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(pemObject.getContent()); KeyFactory factory = KeyFactory.getInstance("RSA"); PublicKey publicKey = factory.generatePublic(pubKeySpec); signature = Signature.getInstance("SHA1WithRSA"); signature.initVerify(publicKey); } catch (Exception e) { e.printStackTrace(); } }
驗證方法
private boolean verify(String source, String sign) { byte[] data = getDecoder().decode(sign); try { signature.update(source.getBytes()); return signature.verify(data); } catch (SignatureException e) { e.printStackTrace(); return false; } }
測試
String source = service.signature(request); String sign = signService.signAndEncode(source); System.out.println(sign); assertTrue(verify(source, sign));
證明,內容沒有被篡改。
其中,ras_public_key.pem文件由openSSL生成。
ls@LS-8500:~$ openssl genrsa -out rsa_private_key.pem 1024 Generating RSA private key, 1024 bit long modulus (2 primes) ...+++++ ...............+++++ e is 65537 (0x010001) ls@LS-8500:~$ openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -----BEGIN PRIVATE KEY----- MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAOk4nqif4LtwfePZ IeGgUc5XYbWk8FpT6UEgO/43i0uprf2RXs3j9eDjOyRwkW2iMCF6S3bNxYuiyJv4 eNc+8w87PJ9bOMRq9WH+ISWIfnPu2x6A1oNOeNkAL7v3ztmpcAn2bNMJ5VscSKp8 S1U02LbHpOErPjvnEul9a/e8xb7TAgMBAAECgYEAvpMeyuoCKQiORo6aqhVoY7Vx yY2jPhyNYUNm4qAeulBINgkBMDtUI1VrcaZun+jFbcXSPp19DFKTnSgYDsOItt04 VLRSZm5yU1EfL21ZvbxIQjjSMv4BxndjdfdoGh6Gve0p1vqtnXtMivkNNI/HdCrx R2CpcGNo4Uqg+zgvwzECQQD1yULuH1sMTEGqLHZaBXVVt1ny+oF+3CnDz2ZdQTWj SLFfBSKplCL8TuEakauUiYf6BVtOjrpzKHRs7hDuZLW5AkEA8umwPbO09ijQdg5e /nkEnJnG5C4krXZuIcsYnf1wrBCLAoOImgDSvVzRrXHMGNvvP0D3gTIxwZSNPt57 1OFe6wJBAJmcOm9WO3IZKqTvetxSMv3qRJY+B7bAZH3TXleEDMDLCsenDv3K7n6f 0cHoLsL7nXcd5+3V+CNGslTuCLjlSkkCQQCM1fqNu5xmwAElAW4IIkgPN4U+FJbF T43I4ATUzPU/fZPrEDHqACIvEhqrcfgATbuns9YMPPrmHmfKFJo9MbGjAkEAzmbW IsDQP4S8TJVd6PvyNZgNrTZvtlMT8/v4MytaEErrljhAR/YLKLcWFxLmQNAL9g4M SsHT8KunE5YrBmkXkg== -----END PRIVATE KEY----- ls@LS-8500:~$ openssl rsa -in rsa_private_key.pem -pubout -out ras_public_key.pem writing RSA key
補充知識:Java導入OpenSSL生成的公私鑰文件
1. 生成2048-bit RSA私鑰
$ openssl genrsa -out private_key.pem 2048
2. 導出RSA公鑰
$ openssl rsa -in private_key.pem -pubout -out public_key.pem
3. 將公私鑰文件private_key.pem和public_key.pem的頭尾注釋去掉
即:
-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
4. 讀取公私鑰文件內容
// filePath即為private_key.pem和public_key.pem public static String getKeyFromFile(String filePath) throws Exception { File file = new File(filePath); InputStream ins = new FileInputStream(file); BufferedReader br = new BufferedReader(new InputStreamReader(ins)); String readLine = null; StringBuffer sb = new StringBuffer(); while ((readLine = br.readLine()) != null) { sb.append(readLine); } br.close(); ins.close(); return new String(sb); }
5. 讀取私鑰
public static PrivateKey getPrivateKey(String privateKey) throws Exception { // 解碼由base64編碼的私鑰 byte[] keyBytes = decryptBASE64(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取得私鑰 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); return priKey; }
6. 讀取公鑰
public static PublicKey getPublicKey(String publicKeyStr) throws Exception { // 解碼由base64編碼的公鑰 byte[] keyBytes = decryptBASE64(publicKeyStr); // 取得公鑰 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); return publicKey; }
以上就是Java讀取OpenSSL實現生成PEM公鑰文件的操作,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。