C#でPFX証明書を使用して要求に署名するには?

b0czek:

私は非公式のAPIドキュメントを利用するようにしようとしています。私は自分自身の証明書を持つすべての要求に署名する必要がありますが、ドキュメントはここにある、使用にのみ、Javaコードを思い付きました:

public class EncryptionUtils {
private static final String ALGORITHM_NAME = "SHA1withRSA";
private static final String CERT_TYPE = "pkcs12";
private static final String CONTAINER_NAME = "LoginCert";
private static final String PASSWORD = "CE75EA598C7743AD9B0B7328DED85B06";

public static String signContent(byte[] contents, final InputStream cert) throws IOException, GeneralSecurityException, NullPointerException {
    final KeyStore instance = KeyStore.getInstance(CERT_TYPE);
    instance.load(cert, PASSWORD.toCharArray());
    final PrivateKey privateKey = (PrivateKey) instance.getKey(CONTAINER_NAME, PASSWORD.toCharArray());
    final Signature instance2 = Signature.getInstance(ALGORITHM_NAME);
    instance2.initSign(privateKey);
    instance2.update(contents);
    return Base64.getEncoder().encodeToString(instance2.sign());
}}

私はこのコードを思いつきました

    private static string password = "CE75EA598C7743AD9B0B7328DED85B06";
    public static string Sign(string text, string cert)
    {
        X509Certificate2 certificate = new X509Certificate2(DecodeCrt(cert), password, X509KeyStorageFlags.Exportable);
        RSA provider = (RSA)certificate.PrivateKey;
        // Hash the data
        var hash = HashText(text);
        // Sign the hash

        var signature = provider.SignHash(hash, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
        return Convert.ToBase64String(signature);

    }
    public static byte[] HashText(string text) 
    {
        SHA1Managed sha1Hasher = new SHA1Managed();
        UnicodeEncoding encoding = new UnicodeEncoding();
        byte[] data = encoding.GetBytes(text);
        byte[] hash = sha1Hasher.ComputeHash(data);
        return hash;
    }
    public static byte[] DecodeCrt(string crt)
    {
        return Convert.FromBase64String(crt);
    }

しかし、出力はJavaのバージョンとは異なります。それも動作するかどうか、私は知っているだろうので、私はC#から一時的に実行するJavaタスクに試してみた、そしてそれがあります。C#でこれを書くための方法はありますか?

Topaco:

両方のコードは、を介してJavaコードで指定された署名PKCS#1 V1.5パディングとRSAとSHA1、使用SHA1withRSA中に明示的にC#コードとにRSA#SignHash2番目と3番目のパラメータを介し方法。署名のPKCS#1 V1.5バリアント(以来RSASSA-PKCS1-v1_5のは)決定論的であり、両方のコードは、(同じデータが署名されると仮定すると、同一の秘密鍵)は、同じ署名を提供しなければなりません。

そうでない場合は、実際には2つだけの合理的な説明があります。

  • まず、符号化が使用:Javaコードでは、データとして転送されbyte[]、それがポストコードに基づいて使用されるエンコーディングを決定することはできませんように。C#コードでは、対照的に、データは、文字列として渡され、に変換byte[]におけるHashTextこの標準CTORためUnicodeEncodingUTF16LEとバイト順マーク(適用に使用され、BOMを)。(BOMなし)UTF8のためにUTF8Encoding使用しなければならないであろう。それはです重要同じ符号は、JavaコードのようなC#コードに適用され、さもなければ異なるシグネチャは、通常、生成されます。
  • 第二に、PFX / P12ファイル:PFX / P12ファイルに含めることができるいくつかの証明書をJavaコードでは、KeyStore#getKeyリファレンスの別名を持つ秘密鍵は(同じ証明書に適用される)、C#コードでは、X509Certificate2(Byte[], String, X509KeyStorageFlags)参照は、最初の容器内の証明書は、も参照ここことを確認するために、同じ証明書/キーは、両方のコードで参照され、PFX / P12ファイルは、そのためだけ含まれていてもよい正確に一つの対応する秘密鍵を含む証明書を。

これは考慮されている場合は、両方のコードが自分のマシン上で同一のシグネチャを生成する(同一データが署名されると仮定すると、同一PFX / P12ファイル)。

最後に、両方のコードに留意すべきであるcert異なるオブジェクトのために使用されます。Javaコードでは、意味InputStream、C#コードでBase64エンコード PFX / PF12ファイルのバイナリデータを。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=285997&siteId=1