-1

PHP 側で openssl_private_decrypt() を使用して復号化するために、C# アプリケーションで文字列を暗号化しようとしています。復号化しようとしている最初の公開鍵は、PHP の openssl_pkey_get_details($privateKey); 内から取得されます。先に話して、私はchilkatを使ってそれを行うことができますが、iOSではモノタッチでは動作しないので役に立ちません(そしてかなりの費用がかかります)。私がそれをやっている方法のコードサンプルがあります:

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

私は何が欠けていますか?

4

1 に答える 1

3

わかりました、タンバリンでシャーマニックダンスをいくつか行った後、私はやや満足のいく解決策にたどり着きました. これはすべて、PHP の openssl_private_decrypt() 関数を使用するコンテキストで行われることに注意してください。

だから私は次を得た:

  1. BouncyCastle の暗号化が正しくない

  2. RSACryptoServiceProvider で使用するために秘密鍵からモジュラスを取得する方法がわかりません

  3. 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); 
    

実際、私が解決策を思いついたのは奇妙なことです。いつか誰かの役に立てば幸いです。

于 2013-12-21T06:38:39.977 に答える