繁体   English   中英

使用RSACryptoServiceProvide在C#中加密,并在PHP中使用openssl_private_decrypt解密

[英]Encrypt in C# using RSACryptoServiceProvide and decrypt using openssl_private_decrypt in PHP

我花了整整一天时间试图使它正常工作,但是没有运气:(

我在C#中使用以下代码进行加密:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
RSAParameters rsaParam = rsa.ExportParameters(false);
rsaParam.Modulus = Convert.FromBase64String("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwlhAsNcNCDRgzCc49u/0iSDrdJn7yoiH/HHipbQp0QSejzg/48mMA6wb32OPQ7qzBgJNvwiQbMvi89BvGNAJ9K8vM0RW7WOqtnb/8IK9BAJVtEwJ3vvKTf5EluiUgWVbGYpWPjbl/lsD3/hRTR0uF46h7q4OlARxOupl9xVS2wQIDAQAB");
rsa.ImportParameters(rsaParam);
string msg = "This is a test.";
byte[] encValue = rsa.Encrypt(Encoding.UTF8.GetBytes(msg), true);
Console.WriteLine(Convert.ToBase64String(encValue));

这是我用来解密的PHP代码。

// Read key
$fp = fopen($KeyPath,"r");
$Key = fread($fp,8192);
fclose($fp);
openssl_private_decrypt($data, $decrypted, openssl_get_privatekey($Key, "123456"));

我使用的私钥(密码为“ 123456”):

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,16B167A1F1E4E61E

A0eOxhU9Fp4ZIkmSpCUOA2VGG8evE71bEz/eO5LlUatUTt4RQcu68mFOM23PdnHl
YqjTV7AwedUu+LsNtjDfy+NJzvvi+re/kpYAD9RWDE0buHGp86vIhxJLCA633JSt
kcMbkFBBbJPBW74FK7Djo2tlE/jKFb4Uy6EIBEsI56pcbdOIKWHTOLHb3/gG8spx
/jPyylR1D1Rm1Nw9mhfQ8c+GZoXYn919Zx9fvKYq5CiH8hqy6q1TCsTjUpdgdkxz
3kDQ6nn4cOCCwCwU2F+iRpzmSE0DORPtCK/rNdhHXaVqm/SvIDSerpX6L4l8NiRx
Vb19htQChysfB7O/XiDVxL8gqSUmMrSujP50NUlyuBEG/32JyCounlX/4JQEGvAN
ALGkLwULhp1D2ATQVck5aNncxcbuB56laf+KZm5E83Tbeu1j4MG+JzJq+kbLVuYi
7TJ1JqjjL4Ixlyh/M23UuViFsw1V0zuZslFhvtq0/hdNXhIgNVmMFPFadOSKMtVY
kTkX7+coEXrtwPV+4ztoH3M2+zwZczkNECbed9H0PPw6uhrOpu+EyGR4qJ/TsMe1
Ht60veBMuPhwC5TqKP8Luz8x57d5Y4+kBFMvQda1b38PUuXSRw2OZ+cBHk0wrET/
pnyOIhg3lvREPvhXpe1oyaSZZLu95xTAj9YSDG+iKToDCD8hgdaRn1Pi6VOaz8Ru
+AUjz0L0fbwrU7jZ3x2L1AGsdwVwmwTL8Fwk/WY8sWu3KCW4olW1nQ8o/4+jO7q9
JvrYW/HxqIxP0Mnc9ODNmaG/NH1q5v7LIPAz47bpqXwdr8hDV/L5mA==
-----END RSA PRIVATE KEY-----

我对加密不熟悉,请问有人可以告诉它如何工作吗? PS:我认为php中的代码很好,因为我分别测试了代码。

您可以使用此代码来加密您的字符串。

public string EncodeData(string sData)
{
    try {
        byte[] encData_byte = new byte[sData.Length];
        encData_byte = System.Text.Encoding.UTF8.GetBytes(sData);
        string encodedData = Convert.ToBase64String(encData_byte);
        return encodedData;
    } catch (Exception ex) {
        throw new Exception("Error in base64Encode" + ex.Message);
    }
}

为了解密您的字符串,您可以使用此代码。

public string DecodeData(string sData)
{
    System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
    System.Text.Decoder utf8Decode = encoder.GetDecoder();
    byte[] todecode_byte = Convert.FromBase64String(sData);
    int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
    char[] decoded_char = new char[charCount];
    utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
    string result = new String(decoded_char);
    return result;
}

试试这个,这将起作用。

谢谢。

您确定RSACryptoProvider正在使用您提供的格式的密钥吗?

我已经看到许多RSACryptoProvider的示例使用基于XML的私钥。 例如。

使用PHP进行RSA签名并使用C#进行验证

"<RSAKeyValue><Modulus>3BqiIB3ouyXHDMpW43TlZrx8fkts2FVVARJKNXFRQ/WIlsthDzL2jY2KEJVN6BKE4A51X+8LMzAI+2z3vIgAQT3bRSfOwygpGBjdhhnXJwFlQ6Gf/+z0ffQfVx/DHw3+QWphcwGDBst+KIA6u6ayy+RDE+jEityyyWDiWqkR9J8=</Modulus><Exponent>AQAB</Exponent><P>8a8nuVhIANh7J2TLn4wWTXhZY1tvlyFKaslOeAOVr+wgEWLQpLZ0Jpjm8aUyyOYPXlk7xrA5BOebtz41diu4RQ==</P><Q>6SQ9y3sEMjrf/c4bHGVlhOj4LUVykradWWUNC0ya7llnR8y1djJ1uUut+EoAa1JQCGukuv4K8NvN1Ieo72Fhkw==</Q><DP>cg0VMusNN5DxNRrk2IrUL4TesfuBQpGMO6554DrY1acZTvsRuNj9IQXA3kH2IEYo9H4prk6U6dKeci/iLLze/Q==</DP><DQ>m/pZNXeZ+RkWnrFzxe24m9FZqMAbxThT0Wkf7v1Tcj9yL8EvbmKYDF4riD/KRAMP9HJABbLNExObg6M3TOAz7Q==</DQ><InverseQ>w8PvW8srrPCuOcphBKXSyoZxCZn81+rovBxuE8AB95m5X+URE8SunK7f+g7hBBin6nUOaVGohBP8jzkQEsdx1Q==</InverseQ>  <D>AsVPDypxOJHkLJQLffeFv8JVqt1WNG72j/nj90JC7KEVpBhRU3inw+ZpO4Y1odtB0vQ7pAaFVJKhOlEH2Va48hNUEQujML8rE+LZXgI3lu0TlqOCIqTHIljeJry0ca30XFtFDp9kh0Kr/0CgGMqgIed+hDUjAad8ke9D2YicDok=</D></RSAKeyValue>"

我搜寻了几天,终于弄清楚了自己:)
我以错误的方式加载参数。

根据RSA公钥结构(PEM):

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwlhAsNcNCDRgzCc49u/0iSDrdJn7yoiH/HHipbQp0QSejzg/48mMA6wb32OPQ7qzBgJNvwiQbMvi89BvGNAJ9K8vM0RW7WOqtnb/8IK9BAJVtEwJ3vvKTf5EluiUgWVbGYpWPjbl/lsD3/hRTR0uF46h7q4OlARxOupl9xVS2wQIDAQAB

我将字符串分为3部分(base64编码):

标头

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC

模量:

wlhAsNcNCDRgzCc49u/0iSDrdJn7yoiH/HHipbQp0QSejzg/48mMA6wb32OPQ7qzBgJNvwiQbMvi89BvGNAJ9K8vM0RW7WOqtnb/8IK9BAJVtEwJ3vvKTf5EluiUgWVbGYpWPjbl/lsD3/hRTR0uF46h7q4OlARxOupl9xVS2wQ

指数:

IDAQAB

(请注意,我仍然不清楚RSA密钥结构。以上只是密钥结构的模糊视图,但是对于那些感兴趣的人,我建议您阅读API文档“ RSAParameters”RSA规范

显然,我正在做的就是将整个密钥字符串导入RSAParameters.Modulus 那不是导入密钥的方法。 这就是为什么它不起作用的原因。

这样做的方法是从密钥文件中提取公共加密所需的modulusexponent 并导入RSAParameters

RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSAParameters RSAKeyInfo = new RSAParameters();
RSAKeyInfo.Modulus = modulus;
RSAKeyInfo.Exponent = exponent;
RSA.ImportParameters(RSAKeyInfo);

然后加密字符串:

RSA.Encrypt("HAHA I GOT IT!!", false);

提取方式。 我建议去JavaScience以获得更多信息。 那里有很多加密实用程序

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM