Java 到 Win32 加密 API

Java to Win32 Crypto API

我有以下 public 密钥从 Java 作为 RSA 生成:

305c300d06092a864886f70d0101010500034b003048024100ab12b3ee64b85bdda7e9744df3210d9b0efc7fbd36385cd903a4f8ee51101bc9c4f0b23583ff090e7d61773e024cbbff4008037cba6538d1c70d865c948716e70203010001

我正在尝试按以下方式导入密钥:

1) 将字符串解码为字节数组(Key)

public static byte[] DecodeKey(string data)
{
    int count = data.Length;
    byte[] key = new byte[count / 2];
    for (int i = 0; i < count ; i += 2)
        key[i / 2] = Convert.ToByte(data.Substring(i, 2), 16);
    return key;
}

2) CryptAcquireContext 使用 Microsoft Strong Cryptographic ProviderPROV_RSA_FULL.
3) 然后用上面的键调用 CryptImportKeykey.Length.

它returns:

Bad Version of provider.

由于历史原因,您的 RSA 密钥在 SubjectPublicKeyInfo format, which is what Java returns when you use the RSAPublicKey.getEncoded() method. Java calls this format an X509EncodeKeySpec 中。

这是 .NET 的不便格式。您可以检查 .NET 类 以查看最方便的格式。我怀疑最方便的格式是 XML 格式。以下 Java 片段将以这种格式输出 RSA public 密钥:

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPublicKey;
import javax.xml.bind.DatatypeConverter;

public class RSAToXML {

    public static void main(String[] args) throws Exception {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024);
        KeyPair keyPair = kpg.generateKeyPair();
        RSAPublicKey rsaPub = (RSAPublicKey) keyPair.getPublic();
        System.out.println("<RSAKeyValue>");
        System.out.print("\t<Modulus>");
        System.out.print(DatatypeConverter.printBase64Binary(rsaPub.getModulus().toByteArray()));
        System.out.println("</Modulus>");
        System.out.print("\t<Exponent>");
        System.out.print(DatatypeConverter.printBase64Binary(rsaPub.getPublicExponent().toByteArray()));
        System.out.println("</Exponent>");
        System.out.println("</RSAKeyValue>");
    }
}

此输出随后可用于将 RSA public 密钥导入 .NET,如以下 C# 片段所示:

    public static void XmlImport()
    {
        var xmlPubKey = "<RSAKeyValue>\n\t<Modulus>AI0hSZ3hcfJHv1TPSIkT0XeW/HMPPFJMw4/aX5NxfhyVacpb5u6rucDztVNG1pXaBdya9OdO1+mGG250y+QuqP/70uu5QMcMEpCdp8xl0i+cUN9+fHDzse4XR/Kdrl3pKAefSR5QQX8xBScjTO+H+9fXVrrU9TQU6WXmahQnDwDJ</Modulus>\n\t<Exponent>AQAB</Exponent>\n</RSAKeyValue>\n";
        var rsa = RSA.Create();
        rsa.FromXmlString(xmlPubKey);
        Console.WriteLine(rsa.ToXmlString(false));
    }

注意:这使用 .NET 类,而不是 Win32 CryptoAPI。几乎没有理由再使用 CryptoAPI。