【问题标题】:adding footer/header to base64 encoded string将页脚/页眉添加到 base64 编码的字符串
【发布时间】:2022-01-07 07:33:11
【问题描述】:

所以我有一个像这样编码的 X509Certificate

String base64 = Base64.getEncoder().encodeToString(certificate.getEncoded());

但这会返回一个看起来像这样的字符串 (MII....) 因此,为什么我相信当我运行这部分时

PEMParser reader= new PEMParser (new StringReader(new String(Base64.getDecoder().decode(base64))));
PemObject object = reader.readPemObject(); 

object 等于 null。 我相信这是因为base64编码的字符串缺少页眉/页脚-----BEGIN CERTIFCATE----------END CERTIFICATE-----

知道如何解决这个问题吗?

【问题讨论】:

    标签: java base64 x509certificate bouncycastle


    【解决方案1】:

    PEM 编码源自 DER 编码,首先通过 Base64 对 DER 数据进行 Base64 编码,每 64 个字符后换行,并添加特定的页眉和页脚行。
    尽管这很容易实现,但 BouncyCastle 为将 DER 转换为 PEM 提供了方便的支持,反之亦然。用于写入 PEM 数据JcaPEMWriter,用于解析 PEM 数据PEMParser
    这不仅适用于证书,还适用于各种格式的公钥和私钥(PKCS#8、X.509/SPKI、PKCS#1)。

    当前的问题是关于证书的转换。在这种情况下,标题行是-----BEGIN CERTIFICATE-----,页脚行是-----END CERTIFICATE-----。以下示例显示了将 PEM 转换为 DER 和将 DER 转换为 PEM 的两个类的使用:

    import java.io.StringReader;
    import java.io.StringWriter;
    import java.util.Base64;
    import org.bouncycastle.openssl.PEMParser;
    import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
    import org.bouncycastle.util.io.pem.PemObject;
    import org.bouncycastle.util.io.pem.PemObjectGenerator;
    
    ...
    
    // PEM encoded certificate
    String cert = "-----BEGIN CERTIFICATE-----\r\n"
            + "MIIFlTCCA32gAwIBAgIJAO4YFLMMLNM2MA0GCSqGSIb3DQEBCwUAMGExCzAJBgNV\r\n"
            ...
            + "nZSJxV3jloZP3NJDIQOZ8zXBqzVfba9fOOZF1ghIa0wFuvH1Ip1vL1sdBdo4PFsY\r\n"
            + "BQfFgCihe1CeDfY3gNQVQSS/dQ5139+kBQBsYnEeWoz0CLQWhGp3B/8=\r\n"
            + "-----END CERTIFICATE-----";
    
    // Convert PEM to DER
    PEMParser pemParser = new PEMParser(new StringReader(cert));
    PemObject pemObject = pemParser.readPemObject(); 
    byte[] derCertificate = pemObject.getContent(); // the DER encoded certificate
    System.out.println(Base64.getEncoder().encodeToString(derCertificate));
    
    // Convert DER to PEM
    StringWriter stringWriter = new StringWriter();
    JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(stringWriter);
    jcaPEMWriter.writeObject((PemObjectGenerator)new PemObject("CERTIFICATE", pemObject.getContent()));
    jcaPEMWriter.close();
    String pemCertificate = stringWriter.toString(); // the PEM encoded certificate
    System.out.println(pemCertificate); 
    

    代码需要 bcprov 和 bcpkix jar 文件。

    同样,私钥和公钥可以相互转换,只需要调整PemObject构造函数中的CERTIFICATE字符串即可:

    format                  string
    ---------------------------------------
    PKCS#8                  PRIVATE KEY
    X.509/SPKI              PUBLIC KEY
    PKCS#1, private         RSA PRIVATE KEY
    PKCS#1, public          RSA PUBLIC KEY
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-23
      • 2021-03-22
      • 1970-01-01
      • 2018-08-17
      相关资源
      最近更新 更多