Acme4jコードはjava.security.cert.X509Certificate
クラスを使用します。このクラスのtoString()
メソッド(Sunのデフォルトプロバイダを使用している場合)は"拡張不明"出力(corresponding codeによる)を生成しています。
これを正しく解析するには(フォーマットされた出力を得るために)、この拡張機能を解析するコードを含め、acme4jのコードを変更する必要があります。私のテストで
は(のJava 7とはBouncyCastle 1.56)、私は(私はほとんどの部分をコピーしてちょうどTNAuthorizationList
拡張のためのコードを追加しました)X509Certificate
にラッパーを作成したとはBouncyCastleのコードに基づいてformat
メソッドを作成しました。以下のコードは最適ではありませんが(例外処理が不十分で、非推奨のクラスがいくつかあります)、あなたはアイデアを得ることができます。
X509Certificate cert = ...
System.out.println("Certificate " + new CertificateWrapper(cert).format());
出力フォーマットは、SUNのデフォルトのプロバイダとは異なり、しかし、あなたはあなたが必要なものを得るためにそれをカスタマイズすることができます。
import org.bouncycastle.asn1.*;
import org.bouncycastle.asn1.misc.*;
import org.bouncycastle.asn1.util.ASN1Dump;
import org.bouncycastle.asn1.x509.*;
import org.bouncycastle.util.encoders.Hex;
public class CertificateWrapper {
private X509Certificate cert;
public CertificateWrapper(X509Certificate cert) {
this.cert = cert;
}
public String format() throws Exception {
StringBuffer buf = new StringBuffer();
String nl = System.getProperty("line.separator");
buf.append(" [0] Version: ").append(this.cert.getVersion()).append(nl);
buf.append(" SerialNumber: ").append(this.cert.getSerialNumber()).append(nl);
buf.append(" IssuerDN: ").append(this.cert.getIssuerDN().toString()).append(nl);
buf.append(" Start Date: ").append(this.cert.getNotBefore()).append(nl);
buf.append(" Final Date: ").append(this.cert.getNotAfter()).append(nl);
buf.append(" SubjectDN: ").append(this.cert.getSubjectDN().toString()).append(nl);
buf.append(" Public Key: ").append(this.cert.getPublicKey()).append(nl);
buf.append(" Signature Algorithm: ").append(this.cert.getSigAlgName()).append(nl);
byte[] sig = this.cert.getSignature();
buf.append(" Signature: ").append(new String(Hex.encode(sig, 0, 20))).append(nl);
for (int i = 20; i < sig.length; i += 20) {
if (i < sig.length - 20) {
buf.append(" ").append(new String(Hex.encode(sig, i, 20))).append(nl);
} else {
buf.append(" ").append(new String(Hex.encode(sig, i, sig.length - i))).append(nl);
}
}
TBSCertificateStructure tbs = TBSCertificateStructure.getInstance(ASN1Sequence.fromByteArray(cert.getTBSCertificate()));
X509Extensions extensions = tbs.getExtensions();
if (extensions != null) {
Enumeration e = extensions.oids();
if (e.hasMoreElements()) {
buf.append(" Extensions: \n");
}
while (e.hasMoreElements()) {
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) e.nextElement();
X509Extension ext = extensions.getExtension(oid);
if (ext.getValue() != null) {
byte[] octs = ext.getValue().getOctets();
ASN1InputStream dIn = new ASN1InputStream(octs);
buf.append(" critical(").append(ext.isCritical()).append(") ");
try {
if (oid.equals(Extension.basicConstraints)) {
buf.append(BasicConstraints.getInstance((ASN1Sequence) dIn.readObject())).append(nl);
} else if (oid.equals(Extension.keyUsage)) {
buf.append(KeyUsage.getInstance((DERBitString) dIn.readObject())).append(nl);
} else if (oid.equals(MiscObjectIdentifiers.netscapeCertType)) {
buf.append(new NetscapeCertType((DERBitString) dIn.readObject())).append(nl);
} else if (oid.equals(MiscObjectIdentifiers.netscapeRevocationURL)) {
buf.append(new NetscapeRevocationURL((DERIA5String) dIn.readObject())).append(nl);
} else if (oid.equals(MiscObjectIdentifiers.verisignCzagExtension)) {
buf.append(new VerisignCzagExtension((DERIA5String) dIn.readObject())).append(nl);
//*********************************************************
// *** HERE: code to handle TNAuthorizationList ***
//*********************************************************
} else if (oid.equals(TNAuthorizationList.TN_AUTH_LIST_OID)) {
buf.append(TNAuthorizationList.getInstance((ASN1Sequence) dIn.readObject())).append(nl);
} else {
buf.append(oid.getId());
buf.append(" value = ").append(ASN1Dump.dumpAsString(dIn.readObject())).append(nl);
}
} catch (Exception ex) {
buf.append(oid.getId());
buf.append(" value = ").append("*****").append(nl);
}
} else {
buf.append(nl);
}
}
}
return buf.toString();
}
}
次に、あなただけX509Certificate
の代わりにこのラッパーを使用しています。
PS:この質問はthis oneを補完する(または "続編")です。 OPコードはhere、TNAuthorizationList
クラスはaccepted answerに入っています。しかし、この質問は別の問題(関連性は異なるが)であるため、別の質問として保管されていた。
どのようにacme4jのコードを正確に使用していますか? –