X509证书公钥填充

时间:2014-01-25 22:56:34

标签: c# java rsa padding x509certificate

我正在将一些Java代码移植到C#,但似乎Java和C#之间的公钥填充不一致。

这是我的Java代码:

package Encryption;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
import java.io.ByteArrayInputStream;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.xml.bind.DatatypeConverter;
/**
 *
 * @author Cameron
 */
public class Encryptiontest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here

        String publicKey = "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";
        ByteArrayInputStream bytearrayinputstream = new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(publicKey));
        X509Certificate x509certificate;
        try
        {
            x509certificate = (X509Certificate)CertificateFactory.getInstance("X.509").generateCertificate(bytearrayinputstream);
            RSAPublicKey key = (RSAPublicKey)x509certificate.getPublicKey();
            System.out.println(DatatypeConverter.printBase64Binary(key.getEncoded()));
        }
        catch (CertificateException certificateexception)
        {
        }
    }

}

当我打印RSAPublicKey的base64表示时,这就是我得到的:

  

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvUihVNnWYpu3uJmcLy + PBecKu4ziVD7OIeZ / V + tJkXbc5 + 6OW8G + QDtJKuJkkuxGNLBNmLHbCyXsJ / US3kKkU7 / 7yK7jfWRNdqAKJdDTVxsWnxlo + / + 28ScGrAV6wK2bbK8GQBpsYRn1HKGCGceWIBCSqUfI7rwgwDnvqcW5PeivORd4 + or5DdhgUMwiV5Vr2fvdcAiQR1CKgMphxO4 OmZ4khpB / HT / xS4FscvfFsSBLM37jBMrnhY5yNKPeHZB2eYvehnnw22NFHJNksa + vVFXL9aJcZWJc / bqqlhlhL8eLdYSR / KA006PSInW8yWtd4IFVKJ1Moa41gCUZL81voQIDAQAB

但是,结果与使用相同base64公钥的C#不同。这是我的C#代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace EncryptionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            String publicKey = "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";
            byte[] data = Convert.FromBase64String(publicKey);

            X509Certificate x509certificate = new X509Certificate(data);
            byte[] rsaPublicKey = x509certificate.GetPublicKey();

            string base64 = Convert.ToBase64String(rsaPublicKey);

            Console.WriteLine(base64);
            Console.ReadKey();
        }
    }
}

C#输出:

  

MIIBCgKCAQEAvUihVNnWYpu3uJmcLy + PBecKu4ziVD7OIeZ / V + tJkXbc5 + 6OW8G + QDtJKuJkkuxGNLBNmLHbCyXsJ / US3kKkU7 / 7yK7jfWRNdqAKJdDTVxsWnxlo + / + 28ScGrAV6wK2bbK8GQBpsYRn1HKGCGceWIBCSqUfI7rwgwDnvqcW5PeivORd4 + or5DdhgUMwiV5Vr2fvdcAiQR1CKgMphxO4 OmZ4khpB / HT / xS4FscvfFsSBLM37jBMrnhY5yNKPeHZB2eYvehnnw22NFHJNksa + vVFXL9aJcZWJc / bqqlhlhL8eLdYSR / KA006PSInW8yWtd4IFVKJ1Moa41gCUZL81voQIDAQAB

为什么两者相似,但填充方式不同?如何使C#输出看起来像Java输出?

2 个答案:

答案 0 :(得分:3)

Java输出是ASN.1 SubjectPublicKeyInfo的DER编码,如RFC 5280, section 4.1中所指定。 C#输出是ASN.1 RSAPublicKey的DER编码,在许多地方都包含RFC 2313, section 7.

Here是一个易于使用的在线ASN.1解码器,我觉得很方便。您可以将base64直接粘贴到表单中并对其进行解码。

我不是真正的.NET专家,但是我想你可以通过使用X509Certificate2类来获得更接近的东西,如果不相同的话。你可以construct an X509Certificate2 object from an X509Certificate object。 X509Certificate2类包含您可以访问的PublicKey属性。该对象似乎具有EncodedKeyValue,并且在看似无穷无尽的链之后获取原始数据。换句话说,比如:

X509Certificate2 x509certificate2 = new X509Certificate2(data);
byte[] rsaPublicKey = x509certificate2.PublicKey.EncodedKeyValue.RawData;

应该有效。但我还没有测试过它。

答案 1 :(得分:0)

这是获取公钥的Base64表示形式的另一种方法:

string base64 = Convert.ToBase64String(x509certificate.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks);

有关详细信息,请参见Exporting a Certificate as BASE-64 encoded .cer