Java密码学 - 6. pem格式的读写

  1. 代码片段 Snippet
  2. PEM格式
  3. PEM延申

代码片段 Snippet

写入

1
2
3
4
5
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();
    }

读公钥

1
2
3
4
5
    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看源码,可查看pem支持的类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        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 也是如此


PEM格式

—–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. 数据并非以bytes的形式存储。全英,ASCII。正文是使用Base64编码。
  2. 内容不是连续的, 而是有回车
  3. —–BEGIN ** —– 开始 —–END **—– 结尾


Base64的工具包

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


PEM延申

Privacy-enhanced Electronic Mail

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结构里

我们在加密邮件中, 会使用到PEM。