c# - X509 证书公钥填充

标签 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 = "MIIGdzCCBV+gAwIBAgIKEpMtNAAIAAKN5TANBgkqhkiG9w0BAQUFADCBizETMBEGCgmSJomT8ixkARkWA2NvbTEZMBcGCgmSJomT8ixkARkWCW1pY3Jvc29mdDEUMBIGCgmSJomT8ixkARkWBGNvcnAxFzAVBgoJkiaJk/IsZAEZFgdyZWRtb25kMSowKAYDVQQDEyFNaWNyb3NvZnQgU2VjdXJlIFNlcnZlciBBdXRob3JpdHkwHhcNMTIwNjA1MTY1OTMzWhcNMTQwNTE5MjIyMzMwWjB1MQswCQYDVQQGEwJVUzELMAkGA1UECBMCV0ExEDAOBgNVBAcTB1JlZG1vbmQxEjAQBgNVBAoTCU1pY3Jvc29mdDESMBAGA1UECxMJWGJveCBMaXZlMR8wHQYDVQQDExZ4cGFzc3BvcnQueGJveGxpdmUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvUihVNnWYpu3uJmcLy+PBecKu4ziVD7OIeZ/V+tJkXbc5+6OW8G+QDtJKuJkkuxGNLBNmLHbCyXsJ/US3kKkU7/7yK7jfWRNdqAKJdDTVxsWnxlo+/28ScGrAV6wK2bbK8GQBpsYRn1HKGCGceWIBCSqUfI7rwgwDnvqcW5PeivORd4+or5DdhgUMwiV5Vr2fvdcAiQR1CKgMphxO4+OmZ4khpB/HT/xS4FscvfFsSBLM37jBMrnhY5yNKPeHZB2eYvehnnw22NFHJNksa+vVFXL9aJcZWJc/bqqlhlhL8eLdYSR/KA006PSInW8yWtd4IFVKJ1Moa41gCUZL81voQIDAQABo4IC8DCCAuwwRAYJKoZIhvcNAQkPBDcwNTAOBggqhkiG9w0DAgICAIAwDgYIKoZIhvcNAwQCAgCAMAcGBSsOAwIHMAoGCCqGSIb3DQMHMB0GA1UdDgQWBBS9zuJeIfYW3Q6Jd9KcoLuNM8CNcTAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwCwYDVR0PBAQDAgSwMB8GA1UdIwQYMBaAFAhC49tOEWbztQjFQNtVfDNGEYM4MIIBCgYDVR0fBIIBATCB/jCB+6CB+KCB9YZYaHR0cDovL21zY3JsLm1pY3Jvc29mdC5jb20vcGtpL21zY29ycC9jcmwvTWljcm9zb2Z0JTIwU2VjdXJlJTIwU2VydmVyJTIwQXV0aG9yaXR5KDgpLmNybIZWaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9tc2NvcnAvY3JsL01pY3Jvc29mdCUyMFNlY3VyZSUyMFNlcnZlciUyMEF1dGhvcml0eSg4KS5jcmyGQWh0dHA6Ly9jb3JwcGtpL2NybC9NaWNyb3NvZnQlMjBTZWN1cmUlMjBTZXJ2ZXIlMjBBdXRob3JpdHkoOCkuY3JsMIG/BggrBgEFBQcBAQSBsjCBrzBeBggrBgEFBQcwAoZSaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9tc2NvcnAvTWljcm9zb2Z0JTIwU2VjdXJlJTIwU2VydmVyJTIwQXV0aG9yaXR5KDgpLmNydDBNBggrBgEFBQcwAoZBaHR0cDovL2NvcnBwa2kvYWlhL01pY3Jvc29mdCUyMFNlY3VyZSUyMFNlcnZlciUyMEF1dGhvcml0eSg4KS5jcnQwPwYJKwYBBAGCNxUHBDIwMAYoKwYBBAGCNxUIg8+JTa3yAoWhnwyC+sp9geH7dIFPg8LthQiOqdKFYwIBZAIBCjAnBgkrBgEEAYI3FQoEGjAYMAoGCCsGAQUFBwMCMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQBhJKcKn7h3/pZK2A5wk6lonJMyra4u3bFLzfvg0HWWiGx+vWCbBA2EJoar8V1yCMKezAQOcJWDKzO5HzY9m+PGm7FZtoYZWmCaYt2+Hlt/X7py3Nhgey/xYBTXb1rnu9jhk84+lG4dSAyyTYrsCgrCG5vsqGM4ZZz7FGOhUWQ4QAZ36vgSoLpOy6/6xpaWor4ritklCmHYYGpyuUuZLBt/Tu44ng2rh98hyxMNgaBfZ1cpqnMyYatWIgPPg8DEuNF4iGaujIFQfrU2VuyiUvFWLA9H5vfVLh5CBYR7qqRda0g4p22FDxdfmLu4Q2iZg+rbGxu9+g/9AdAXvhMEjvqC";
            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 输出?

最佳答案

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,您可能会得到更接近的东西,如果不完全相同的话。类(class)。你可以construct an X509Certificate2 object from an X509Certificate object . X509Certificate2 类包含一个 PublicKey您可以访问的属性。该对象似乎有一个 EncodedKeyValue,沿着这个看似无穷无尽的链,您可以获得原始数据。换句话说,类似于:

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

应该可以。但我还没有测试过。

关于c# - X509 证书公钥填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21357323/

相关文章:

c# - iTextSharp PdfTextExtractor GetTextFromPage 抛出 NullReferenceException

java - 使用 jtable 以外的组件检索数据库值?

java - 在Android中调用一个变量的Intent

java - 立方曲线JavaFX

go - 如何将公共(public) RSA key 转换为 JSON Web key

c# - 如何在 Controller 中访问 IApplicationBuilder?

c# - 如何将参数传递给服务器端 Blazor 中的 razor 组件?

c#:将网页的html源读入字符串

c# - 使用 RSA 公钥解密使用 RSA 私钥加密的字符串

java - 无法使用开放式 SSL 解密 RSA 数据