Javaで拡張情報のついたCSRを作成

ググっても日本語では中々ヒットしない内容なので、あまり需要はないかもしれませんが、、、

##動作環境
使用したBouncy Castleのバージョンは下記の通り。古すぎいいいいいい！

* bcpkix-jdk15on-149.jar
* bcprov-ext-jdk15on-149.jar

##秘密鍵・公開鍵・拡張情報付きCSRの作成
```Java
public class CreateExtensionCsr {
    public static void main(String[] args) throws Exception {
        // 暗号化キーを安全に二点間で交換するためのRSA暗号化キーを生成する.
        KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
        keygen.initialize(2048);
        KeyPair keyPair = keygen.generateKeyPair();

        // 秘密キー
        PrivateKey privateKey = keyPair.getPrivate();

        // 公開キー
        PublicKey publicKey = keyPair.getPublic();

        // CSRを作成
        Security.addProvider(new BouncyCastleProvider());
        PKCS10CertificationRequest certReq = generateRequest(privateKey, publicKey);
        
        // PEM形式に変換
        String csr = toPem(certReq);

        System.out.println(csr);
    }

    /**
     * 拡張情報を付与したCSRを作成
     */
    public static PKCS10CertificationRequest generateRequest(PrivateKey privateKey,
            PublicKey publicKey) throws Exception {
        Vector oids = new Vector();
        Vector values = new Vector();

        // 拡張情報の作成
        oids.add(X509Extensions.SubjectKeyIdentifier);
        values.add(new X509Extension(false, new DEROctetString(new SubjectKeyIdentifierStructure(
                publicKey))));
        oids.add(X509Extensions.KeyUsage);
        values.add(new X509Extension(true, new DEROctetString(new KeyUsage(
                KeyUsage.digitalSignature))));

        // 拡張情報の付与
        X509Extensions extensions = new X509Extensions(oids, values);
        Attribute attribute =
                new Attribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, new DERSet(
                        extensions));

        // CSRの作成
        return new PKCS10CertificationRequest("SHA256withRSA", new X500Principal(
                "C=JP"), publicKey, new DERSet(
                attribute), privateKey);
    }

    /**
     * PEM形式に変換
     */
    private static String toPem(Object obj) throws IOException {
        StringWriter sw = new StringWriter();
        PEMWriter writer = null;
        try {
            writer = new PEMWriter(sw);
            writer.writeObject(obj);
            writer.flush();
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
        return sw.toString();
    }
}
```

##CSRの内容確認
```linux-config
$ openssl req -text -noout -in testcreate.csr
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=JP
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b4:ed:73:b2:3a:02:d6:e5:6c:33:29:98:0a:cc:
                    f8:74:43:e0:04:8b:98:1f:f0:4d:1c:28:6e:b4:ec:
                    <<省略>>
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Key Identifier:
                00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:0
            X509v3 Key Usage: critical
                Digital Signature
    Signature Algorithm: sha256WithRSAEncryption
         8d:b7:fd:e2:14:04:7a:85:02:f1:d5:49:c0:02:c8:f2:46:72:
         b9:b5:f5:b3:e3:cf:06:ae:44:7a:37:12:b2:3d:7b:86:d0:db:
         <<省略>>
```