2013-12-20 81 views
-1

我想加密C#应用程序中的字符串,以便在PHP一侧用openssl_private_decrypt()解密。 我试图解密的初始公钥是从PHP的openssl_pkey_get_details($ privateKey)中获得的; 提前谈论,我能够使用chilkat做到这一点,但它不适用于iOS下的monotouch,所以对我来说它是无用的(而且它的成本也相当高)。 有代码示例如何我做它:RSA C#加密公钥与PHP一起使用openssl_private_decrypt():Chilkat,BouncyCastle,RSACryptoServiceProvider

void TestEncryption(string publicKey, string data) 
{ 
     var bytes = Encoding.UTF8.GetBytes(data); 

     //by using chilkat 
     var key = new Chilkat.PublicKey(); 
     var result = key.LoadOpenSslPem(publicKey); 
     var ck = new Chilkat.Rsa(); 
     ck.UnlockComponent("blablabla"); 
     var keyXml = key.GetXml(); 
     ck.ImportPublicKey(keyXml); 
     var ckBytes = ck.EncryptBytes(bytes, false); 

     //by using BouncyCastle 
     Object obj; 
     using (TextReader sr = new StringReader(publicKey)) 
     { 
      PemReader pem = new PemReader(sr); 
      obj = pem.ReadObject();    
     } 
     var par = obj as Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters; 
     RsaEngine e = new RsaEngine(); 
     e.Init(true, par);   
     var bcBytes = e.ProcessBlock(bytes, 0, bytes.Length); 

     //RSACryptoServiceProvider. don't know exectly how to initialize it, one way that must work i think is from chilkat's xml, just to test 
     RSACryptoServiceProvider csp = new RSACryptoServiceProvider(1024); 
     csp.FromXmlString(keyXml); 

     //also tryed to initialize like this: 
     //var pp = csp.ExportParameters(false); 
     //pp.Modulus = byteKey; //this one is publicKey, stripped from --begin-- and --end-- sections and encoded from base64 to byte array (162 bytes) 
     //csp.ImportParameters(pp); 
     // 
     //or if i do 
     //var pp = new RSAParameters(); 
     //pp.Exponent = Convert.FromBase64String("AQAB"); 
     //pp.Exponent array is the same: {1, 0, 1}; 

     var cspBytes = csp.Encrypt(bytes, false); //or (bytes, true), doesn't matter   

     //this function sends request to php and returns result of decryption attempt   
     Debug.WriteLine(ExecRequest(ckBytes)); 
     Debug.WriteLine(ExecRequest(bcBytes)); 
     Debug.WriteLine(ExecRequest(cspBytes)); 
} 

输出为:

success 
decryption failed 
decryption failed 

我失去了什么?

+0

-1并搁置?大声笑。我问的是显而易见的:如何用C#应用程序中的RSA加密数据,以便使用PHP的openssl_private_decrypt()解密这些数据。而不是为此使用奇尔卡特。目前尚不清楚为什么BouncyCastle的加密技术不起作用,以及如何获得RSACryptoServiceProvider使用的公钥模数 –

+0

有两种类型的人通常会帮助您。有些人已经完成了*你正在做的事情,因此可以很容易地发现“缺少的东西”。然后有些人想要帮助你,如果他们能够抓住一些展示问题的代码并使用它。由于第一类通常非常小,因此您希望针对第二类,因此您应该始终努力提供1)足够的有关该问题的信息,即使那些不是该领域专家的人也能够理解这一点, 2)包含所有必要数据的完整示例。 –

+0

如果有些数据丢失,我很抱歉,但我试着让代码示例最大限度地平易近人。我甚至将我的测试样本重写为最小,但仍然完整。请告诉我第二类人可能会失踪的信息。什么必要的数据?此代码可以通过PHP,任何C#IDE和弹性城堡库生成公钥和私钥进行测试。 http://www.visualstudio.com/en-US/products/visual-studio-express-vs http://www.bouncycastle.org/csharp/ –

回答

3

好吧,在与铃鼓做一些萨满舞蹈之后,我得到了一些令人满意的解决方案。 请记住,这一切都是在使用PHP的openssl_private_decrypt()函数的情况下完成的。

所以我就下一个:

  1. BouncyCastle的加密只是做不对

  2. 我不知道怎么弄出来模私钥与的RSACryptoServiceProvider

  3. 使用
  4. 为什么不尝试使用BouncyCastle的密钥数据并初始化RSACryptoServiceProvider

    Object obj; 
    using (TextReader sr = new StringReader(publicKey)) 
    { 
        PemReader pem = new PemReader(sr); 
        obj = pem.ReadObject();    
    } 
    var par = obj as Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters; 
    
    RSACryptoServiceProvider csp = new RSACryptoServiceProvider(1024);   
    //var pp = csp.ExportParameters(false); //works on native .NET, doesn't work on monotouch 
    var pp = new RSAParameters(); 
    pp.Modulus = par.Modulus.ToByteArrayUnsigned(); //doesn't work with ToByteArray() 
    pp.Exponent = par.Exponent.ToByteArrayUnsigned();       
    csp.ImportParameters(pp); 
    var cspBytes = csp.Encrypt(bytes, false); 
    

实际上,我很奇怪的是,我已经想出了解决方案,因为这些细微之处。 我希望有一天会对他有帮助。