最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java讀取OpenSSL生成的PEM公鑰文件操作

 更新時(shí)間:2020年10月07日 15:10:48   作者:此心光明-超然  
這篇文章主要介紹了Java讀取OpenSSL生成的PEM公鑰文件操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧

JDK8的JCE是不支持讀取PEM文件的。需要使用bouncycastle。

項(xiàng)目需求,使用SHA1WithRSA算法,對(duì)接口數(shù)據(jù)做簽名。

代碼如下:

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

單元測試,驗(yàn)證簽名是否正確。先初始化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();
  }
 }

驗(yàn)證方法

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

證明,內(nèi)容沒有被篡改。

其中,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
VLRSZm5yU1EfL21ZvbxIQjjSMv4BxndjdfdoGh5Gve0p1vqtnXtMivkNNI/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

補(bǔ)充知識(shí):Java導(dǎo)入OpenSSL生成的公私鑰文件

1. 生成2048-bit RSA私鑰

$ openssl genrsa -out private_key.pem 2048

2. 導(dǎo)出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. 讀取公私鑰文件內(nèi)容

// 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公鑰文件操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 在Java中動(dòng)態(tài)執(zhí)行字符串代碼的方法小結(jié)

    在Java中動(dòng)態(tài)執(zhí)行字符串代碼的方法小結(jié)

    在Java編程中,靜態(tài)編譯的特性通常不允許我們直接執(zhí)行運(yùn)行時(shí)生成的代碼,然而,有時(shí)我們需要?jiǎng)討B(tài)地生成并執(zhí)行代碼片段,本文將詳細(xì)介紹如何在Java中運(yùn)行一段字符串代碼,并提供詳細(xì)的代碼案例和運(yùn)行結(jié)果,需要的朋友可以參考下
    2024-08-08
  • 基于SpringBoot2.0版本與老版本的區(qū)別

    基于SpringBoot2.0版本與老版本的區(qū)別

    這篇文章主要介紹了SpringBoot2.0版本與老版本的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Maven和IntelliJ IDEA搭建多模塊微服務(wù)的實(shí)現(xiàn)

    Maven和IntelliJ IDEA搭建多模塊微服務(wù)的實(shí)現(xiàn)

    本文主要介紹了Maven和IntelliJ IDEA搭建多模塊微服務(wù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • Java?GUI實(shí)現(xiàn)多個(gè)窗口切換效果

    Java?GUI實(shí)現(xiàn)多個(gè)窗口切換效果

    這篇文章主要為大家詳細(xì)介紹了Java?GUI實(shí)現(xiàn)多個(gè)窗口的切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 詳解Java中的Lambda表達(dá)式

    詳解Java中的Lambda表達(dá)式

    這篇文章主要介紹了Java中的Lambda表達(dá)式的的相關(guān)資料,文中講解非常詳細(xì),示例代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • 解決Lombok注解不起作用的問題

    解決Lombok注解不起作用的問題

    這篇文章主要介紹了解決Lombok注解不起作用的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 詳解Java線程池的使用及工作原理

    詳解Java線程池的使用及工作原理

    在日常開發(fā)過程中總是以單線程的思維去編碼,沒有考慮到在多線程狀態(tài)下的運(yùn)行狀況.由此引發(fā)的結(jié)果就是請(qǐng)求過多,應(yīng)用無法響應(yīng).為了解決請(qǐng)求過多的問題,又衍生出了線程池的概念.本文記錄了Java中線程池的使用及工作原理,需要的朋友可以參考下
    2021-05-05
  • 淺談spring 常用注解

    淺談spring 常用注解

    這篇文章主要介紹了淺談spring 常用注解,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Java中的線程池如何實(shí)現(xiàn)線程復(fù)用

    Java中的線程池如何實(shí)現(xiàn)線程復(fù)用

    這篇文章主要介紹了Java中的線程池如何實(shí)現(xiàn)線程復(fù)用問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • Idea代理設(shè)置與Java程序的代理設(shè)置方式

    Idea代理設(shè)置與Java程序的代理設(shè)置方式

    文章總結(jié):學(xué)習(xí)WebService時(shí),使用Fiddler抓取包數(shù)據(jù),發(fā)現(xiàn)Idea代理設(shè)置與Java程序代理設(shè)置不同,Java程序需要在發(fā)送請(qǐng)求前設(shè)置代理,代碼如下
    2025-01-01

最新評(píng)論

车险| 五大连池市| 息烽县| 宜良县| 磐安县| 山东| 磐石市| 手机| 金湖县| 郧西县| 兖州市| 丹巴县| 英吉沙县| 农安县| 南安市| 崇明县| 宜春市| 禹州市| 谢通门县| 长治市| 西和县| 广饶县| 绵竹市| 霍城县| 宿迁市| 巢湖市| 老河口市| 弋阳县| 九江县| 牡丹江市| 巴马| 蓬安县| 荥阳市| 桑植县| 莱州市| 天水市| 陆良县| 读书| 望江县| 筠连县| 鄯善县|