Java Framework から openssl 証明書を管理するときに問題が発生しています。
openssl x509 -subject_hash ...
出力は、Java フレームワークが を呼び出したときに返すものとは異なりX509_NAME_hash()
ます。以下を参照してください。
これは、openssl が SHA1 の計算方法を変更したためです。現在、MD5 の場合のようにサブジェクトの ASN.1 DER 表現に基づいてハッシュを作成する代わりに、まず CANONICAL 表現を計算し、次にそれに基づいて ASN.1 DER を計算し、それをSHA1 アルゴリズムの入力。
NativeCrypto.java :
// --- X509_NAME -----------------------------------------------------------
public static int X509_NAME_hash(X500Principal principal) {
return X509_NAME_hash(principal, "SHA1");
}
private static int X509_NAME_hash(X500Principal principal, String algorithm) {
try {
byte[] digest = MessageDigest.getInstance(algorithm).digest(principal.getEncoded());
return Memory.peekInt(digest, 0, ByteOrder.LITTLE_ENDIAN);
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
}
Javaの下層でそれを修正しようとするために、opensslライブラリをx_name.c
調べていました。x509_cmp.c
しかし、私は成功しませんでした。
X509_NAME_hash
のメソッドを変更する必要があることを理解していx509_cmp.c
ます。しかし、その変更が直前か直後かはわかりませんi2d_X509_NAME(x,NULL);
。このメソッドは、サブジェクト名のCANONICAL表現を計算していますよね? 次に、その出力に基づいて ASN1 DER を計算する必要がありますよね? しかし、私はそれを作ることができません。
この問題を解決するために、誰かが私を案内したり、これについて何らかの光を当てたりしていただければ幸いです。
x509_cmp.c :
unsigned long X509_NAME_hash(X509_NAME *x)
{
unsigned long ret=0;
unsigned char md[SHA_DIGEST_LENGTH];
/* Make sure X509_NAME structure contains valid cached encoding */
i2d_X509_NAME(x,NULL);
if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
NULL))
return 0;
ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
)&0xffffffffL;
return(ret);
}
この関数x509_name_canon
は明らかに再エンコードを実行します。これは次のcrypto/asn1/x_name.c
とおりです。
/* This function generates the canonical encoding of the Name structure.
* In it all strings are converted to UTF8, leading, trailing and
* multiple spaces collapsed, converted to lower case and the leading
* SEQUENCE header removed.
*
*/