1. 程式人生 > >5. pem格式的讀寫

5. pem格式的讀寫

pem的特徵

程式碼

public static void storeToPem(Object key, String file) throws IOException {
        JcaPEMWriter pemWriter = new JcaPEMWriter(new OutputStreamWriter(FileUtils.openOutputStream(new File(file))));
        pemWriter.writeObject(key);
        pemWriter.close();
    }

讀公鑰

    public
static PublicKey getPemPublic(String fileName) throws IOException { PEMParser pp = new PEMParser(new FileReader(fileName)); PEMKeyPair pemKeyPair = (PEMKeyPair) pp.readObject(); return new JcaPEMKeyConverter().getKeyPair(pemKeyPair).getPublic(); }

這裡值得注意, 並不是我們寫什麼, 就都什麼, 它內部有進行處理, 所以我們必須看原始碼
點選 pp.readObject看原始碼

,選擇對應的型別

        parsers.put("CERTIFICATE REQUEST", new PKCS10CertificationRequestParser());
        parsers.put("NEW CERTIFICATE REQUEST", new PKCS10CertificationRequestParser());
        parsers.put("CERTIFICATE", new X509CertificateParser());
        parsers.put("TRUSTED CERTIFICATE", new X509TrustedCertificateParser());
        parsers.put("X509 CERTIFICATE"
, new X509CertificateParser()); parsers.put("X509 CRL", new X509CRLParser()); parsers.put("PKCS7", new PKCS7Parser()); parsers.put("CMS", new PKCS7Parser()); parsers.put("ATTRIBUTE CERTIFICATE", new X509AttributeCertificateParser()); parsers.put("EC PARAMETERS", new ECCurveParamsParser()); parsers.put("PUBLIC KEY", new PublicKeyParser()); parsers.put("RSA PUBLIC KEY", new RSAPublicKeyParser()); parsers.put("RSA PRIVATE KEY", new KeyPairParser(new RSAKeyPairParser())); parsers.put("DSA PRIVATE KEY", new KeyPairParser(new DSAKeyPairParser())); parsers.put("EC PRIVATE KEY", new KeyPairParser(new ECDSAKeyPairParser())); parsers.put("ENCRYPTED PRIVATE KEY", new EncryptedPrivateKeyParser()); parsers.put("PRIVATE KEY", new PrivateKeyParser());

另外

  1. PemReader和PEMParser ,PEMReader的關係
    • PEMReader是PEMParser 的前身, PEMReader已經廢棄了. 兩者屬於openssl
    • PEMParser使用了PemReader, 區別在於, parser不僅包含PemReader還包含Openssl的內容
    • -
  2. JcaPEMWriter 也是如此

參考資料 :

—–BEGIN RSA PRIVATE KEY—–
MIICWwIBAAKBgQCx3MfExH8NJ96y9ABRg+DYyRTwUgvW7re4kgUsrpbkQD/99+ma
DpmvfuTHIv7+qRk+rLtcbKDy5eqasg2tBjLvYo4rH0MU3/GIGnLlQ6tZyu2BFxOY
lyLdDLdua8nXY1WFcRQ0H3FQeEFBAr+J0QMVXVHiGR/FnL9Hidscz4gjYwIDAQAB
AoGAMwpvjYjyCN1zLBmXac0VnkB+MMTqvuA8esv0jjD//jpt4rzdHaeo9NLOZlMl
qADwzKqXDdviiDHwlDoacJfBz7Ky/t7/9s4XxaPNB6badjrqd256NFE3RN6AoJHE
r30QaLPT5P1d7bJVeNjnm7NVFDd6dD9YeTm5lVbUrFSJcpECQQD4K2BCFAG4BDTS
7GHZcVu6avmMxIN9TpetQ04xgzVi9GPo42S8SDT4iWFu3J0fZE4XbxyxGQyUaTdw
p0NOPxLZAkEAt3l9Sh9iBdk14iXqsL+eri5nIYdwTxI3w5cKIUtkvMwmvf2XP4MR
ZS+u7GYUxKqWC2nRrGckX6xOrjndKe1KmwJAaMwQYvcF3spP8D4H+AXJoYgpB4u4
pwK4RF9mtrvcoIPpaOAVmvi2/bkt3t3kr+vwmi6+o/6a9FUWJ0lKv9EcyQJAAjnE
DlEhJEcFQ1AIb8pzR1OixqJY92yWJpY/djXu6+diFO3tlsSlQl/4tD9swxH6rfrD
o17A7zQs5Coph6esPwJAGlMvupZRz98cQH/vv92usSBn1YbMpvP9qtQzq3Hm2ow6
X9yrrUiwy0rXgxxnoVTIbeMg9eaEAXxaqUE9zGi4CQ==
—–END RSA PRIVATE KEY—–

  1. 非位元組流寫入, 全英文, 所以編碼為ASCII ,至於轉碼, 是使用到Base64
  2. 內容不是連續的, 而是有回車
  3. —–BEGIN ** —– 開始
    —–END **—– 結尾

哪些Base64的包是可以做除這種效果 (此部分可以跳)

  1. apache的Base64不可以 ,但是轉換功能很豐富
  2. bouncycastle的util也不可以
  3. sun的Base64Encoder可以, 但是其他功能不大好, 不能轉換成byte[]

PEM的擴充套件瞭解:

PEM is a de facto file format for storing and sending cryptography keys, certificates, and other data, based on a set of 1993 IETF standards defining “privacy-enhanced mail.”
Many cryptography standards use ASN.1 to define their data structures, and Distinguished Encoding Rules (DER) to serialize those structures.[1] Because DER produces binary output, it can be challenging to transmit the resulting files through systems, like electronic mail, that only support ASCII. The PEM format solves this problem by encoding the binary data using base64. PEM also defines a one-line header, consisting of “—–BEGIN “, a label, and “—–”, and a one-line footer, consisting of “—–END “, a label, and “—–”. The label determines the type of message encoded. Common labels include “CERTIFICATE”, “CERTIFICATE REQUEST”, and “PRIVATE KEY”.

  1. PEM的作用: 儲存和傳送加密金鑰和證書, 以及其他資料
  2. 通過DER的方式儲存在ASN.1結構裡

我們在加密郵件中, 會使用到