Java到Win32加密API

时间:2015-03-06 13:59:41

标签: java c# c cryptography

我从Java生成以下公钥作为RSA:

305c300d06092a864886f70d0101010500034b003048024100ab12b3ee64b85bdda7e9744df3210d9b0efc7fbd36385cd903a4f8ee51101bc9c4f0b23583ff090e7d61773e024cbbff4008037cba6538d1c70d865c948716e70203010001

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

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

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)然后使用上面的密钥和CryptImportKey拨打key.Length

它返回:

  

提供商的错误版本。

1 个答案:

答案 0 :(得分:1)

您的RSA密钥采用SubjectPublicKeyInfo格式,这是Java在您使用RSAPublicKey.getEncoded()方法时返回的格式。由于历史原因,Java将此格式称为X509EncodeKeySpec

这是.NET的一种不方便的格式。您可以检查.NET类以查看哪种格式最方便。我怀疑最方便的格式是XML格式。以下Java代码段将以此格式输出RSA公钥:

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公钥导入.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。