Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 来自Flex客户端的RSA加密和来自Web服务的相应解密_C#_Wcf_Apache Flex_Actionscript 3_Public Key Encryption - Fatal编程技术网

C# 来自Flex客户端的RSA加密和来自Web服务的相应解密

C# 来自Flex客户端的RSA加密和来自Web服务的相应解密,c#,wcf,apache-flex,actionscript-3,public-key-encryption,C#,Wcf,Apache Flex,Actionscript 3,Public Key Encryption,在flex客户端和用c#编写的web服务之间设置RSA加密/解密机制时遇到问题。想法是这样的:我将对flex中的一些文本进行加密,然后从web服务对其进行解密。我正在使用谷歌的as3crypto库。它正在正确加密/解密文本。我在web服务端也有正确加密/解密的代码。我的问题是同步它们——基本上是将公钥共享到flex,并将私钥保留到web服务 我的flex“encrypt”函数使用RSA的模和指数来进行文本加密,那么我如何从web服务的RSACryptServiceProvider获取这些模和指数

在flex客户端和用c#编写的web服务之间设置RSA加密/解密机制时遇到问题。想法是这样的:我将对flex中的一些文本进行加密,然后从web服务对其进行解密。我正在使用谷歌的as3crypto库。它正在正确加密/解密文本。我在web服务端也有正确加密/解密的代码。我的问题是同步它们——基本上是将公钥共享到flex,并将私钥保留到web服务

我的flex“encrypt”函数使用RSA的模和指数来进行文本加密,那么我如何从web服务的RSACryptServiceProvider获取这些模和指数属性,以便它们使用相同的标准。 我试过了 RSAKeyInfo.模数 RSAKeyInfo.指数 从web服务中获取并将它们提供给flex客户端。 在flex上进行加密之后,我获取密码文本并将其提供给web服务上的解密方法,但它给了我“坏数据”错误消息

System.Security.Cryptography.CryptographicException: Bad Data.

   at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
   at System.Security.Cryptography.Utils._DecryptKey(SafeKeyHandle hPubKey, Byte[] key, Int32 dwFlags)
   at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
   at Microsoft.Samples.Security.PublicKey.App.RSADecrypt(Byte[] DataToDecrypt, RSAParameters RSAKeyInfo, Boolean DoOAEPPadding) in C:\Users
\Me\Desktop\After Release\5-24-2011-webServiceCrypto\publickeycryptography\CS\PublicKeyCryptography\PublicKey.cs:line 219
Encryption failed.
如何确保它们都使用相同的字节64或128加密。ie来自flex的输入应该符合web服务提供者的解密方法的期望。 (我想尺寸可能是个问题,可能不是-我迷路了)

下面是代码,首先是flex客户端,然后是web服务c代码

web服务部分如下所示:

       try
        {
            //Create a UnicodeEncoder to convert between byte array and string.
            UnicodeEncoding ByteConverter = new UnicodeEncoding();

            //Create byte arrays to hold original, encrypted, and decrypted data.
            byte[] dataToEncrypt = ByteConverter.GetBytes("Data to Encrypt");
            byte[] encryptedData;
            byte[] decryptedData;

            //Create a new instance of RSACryptoServiceProvider to generate
            //public and private key data.
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                //Pass the data to ENCRYPT, the public key information 
                //(using RSACryptoServiceProvider.ExportParameters(false),
                //and a boolean flag specifying no OAEP padding.
                encryptedData = RSAEncrypt(dataToEncrypt, RSA.ExportParameters(false), false);
                //Pass the data to DECRYPT, the private key information 
                //(using RSACryptoServiceProvider.ExportParameters(true),
                //and a boolean flag specifying no OAEP padding.
                decryptedData = RSADecrypt(encryptedData, RSA.ExportParameters(true), false);
                //Display the decrypted plaintext to the console. 
                Console.WriteLine("\n\nDecrypted plaintext: {0}", ByteConverter.GetString(decryptedData));
            }
        }

static public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
    {
        try
        {
            byte[] encryptedData;
            //Create a new instance of RSACryptoServiceProvider.
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {

                //Import the RSA Key information. This only needs
                //toinclude the public key information.
                RSA.ImportParameters(RSAKeyInfo);

                //Encrypt the passed byte array and specify OAEP padding.  
                //OAEP padding is only available on Microsoft Windows XP or
                //later.  
                encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
            }
            return encryptedData;
        }
        //Catch and display a CryptographicException  
        //to the console.
        catch (CryptographicException e)
        {
            Console.WriteLine(e.Message);

            return null;
        }

    }


 static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
    {
        try
        {
            Console.WriteLine("Modulus Lenghth :" + RSAKeyInfo.Modulus.Length);
            Console.WriteLine("Exponent Length :" + RSAKeyInfo.Exponent.Length);
            byte[] decryptedData;
            //Create a new instance of RSACryptoServiceProvider.
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                //Import the RSA Key information. This needs
                //to include the private key information.
                RSA.ImportParameters(RSAKeyInfo);

                //Decrypt the passed byte array and specify OAEP padding.  
                //OAEP padding is only available on Microsoft Windows XP or
                //later.  
                decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
            }
            return decryptedData;
        }
        //Catch and display a CryptographicException  
        //to the console.
        catch (CryptographicException e)
        {
            Console.WriteLine(e.ToString());

            return null;
        }

    }
我不太确定这个RSA设置是否可行。。。 欢迎任何意见/建议/或建议的解决方案,
谢谢大家

我使用as3crypto和javaweb服务。以下是一些想法:

a。我通过openssl生成了我的公共和私有RSA密钥

b。我的客户机在应用程序启动时加载public.cer文件(如果您只是从生成的密钥中硬编码了它们,那么它也可以工作)

c。通过

var inputByteArray : ByteArray = Hex.toArray(Hex.fromString(inputString));
var outputByteArray : ByteArray = new ByteArray();
appSettingsModel.publicRSAKey.encrypt(inputByteArray, outputByteArray, inputByteArray.length);
d。我没有写JAVA方面的东西,但你也没有用JAVA。我知道as3crypto默认使用PKCS1填充:

RSAKEY.as

private function _encrypt(op:Function, src:ByteArray, dst:ByteArray, length:uint, pad:Function, padType:int):void {
            // adjust pad if needed
            if (pad==null) pad = pkcs1pad;

这是可以改变的,但我还没有尝试过。根据您的代码,看起来您可能正在尝试使用OAEP方案解密,但我无法告诉您如何设置该bool。您可能想看看bool使用的填充方案是什么,并尝试改变一边或另一边以匹配填充策略。

似乎过于复杂。我以前在一些高安全系统上工作过,但这太可笑了。除非你不想让用户知道他刚刚输入的文本,否则为什么在发送的文本中需要这种加密级别


只需使用一个强SSL密钥(IE6的最大值为256bit,您可以使用512,但只能与较新的浏览器兼容)作为具有二进制数据格式(AMF)的实际传输协议(我想象HTTP),一切都应该很好。我怀疑你的系统对于利用加密文本的使用是否如此重要。

Eureka!尤里卡!我明白了

问题是在从web服务解密后,加密的字节数组缺少0,因此当更改为字符串时,它将无法读取“??”文本。所以我只需要使用paddWithZeros()函数,将解密后的字节数组在字节之间填充0,就可以了

感谢凯文,你的解决方案让我洞察了我应该考虑的事情。因此,在解密过程中,我将参数fOAEP指定为false,因此它将使用PKCS#1进行填充(使两个库使用相同的标准)

我得到的另一个错误是坏数据异常。当我将RSA cryptoServiceProvider的参数(模数和指数)共享给actionScript方法时,这个问题得到了解决

我还将c#RSA属性(如模n、指数e、私有d…等)的byte[]数组更改为hexa string,以便能够与as3crypto库共享

我很乐意与大家分享对我有用的东西;节省别人一些时间

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

    <fx:Script>
        <![CDATA[
            import com.hurlant.crypto.Crypto;
            import com.hurlant.crypto.rsa.RSAKey;
            import com.hurlant.crypto.symmetric.ICipher;
            import com.hurlant.crypto.symmetric.IPad;
            import com.hurlant.util.Hex;

            private var currentResult:String;
            private var encryptedText:String;
            private var decryptedText:String;

            private function encrypt(plainText:String):String {
                var rsa:RSAKey = RSAKey.parsePublicKey(getModulus(), getExponent());
                var data:ByteArray = Hex.toArray(Hex.fromString(plainText));  //returns byteArray of plainText
                var dst:ByteArray = new ByteArray;
                rsa.encrypt(data, dst, data.length);
                currentResult = Hex.fromArray(dst);
                encryptedText = currentResult;
                trace ("Cipher: " + currentResult);
                return currentResult;
            }

            private function getInput():ByteArray {
                return null;
            }

            private function getModulus():String {
                return "b6a7ca9002b4df39af1ed39251a5d"; //read this value from web service.
            }

            private function getExponent():String {
                return "011"; //read this value from web service.
            }

            //For debugging and testing purposes
            // private function decrypt(cipherText:String):String {
                // var rsa:RSAKey = RSAKey.parsePrivateKey(getModulus(), getExponent(), getPrivate(), getP(), getQ(), getDMP1(), getDMQ1(), getCoeff());
                // var data:ByteArray = Hex.toArray(cipherText);
                // var dst:ByteArray = new ByteArray;
                // rsa.decrypt(data, dst, data.length);
                // decryptedText = Hex.fromArray(dst);
                     //trace('decrypted : ' + decryptedText);
                // return Hex.toString(decryptedText);
            // }

        ]]>
    </fx:Script>

    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <mx:VBox >
        <s:Button label="Encrypt Text" click="encrypt('my plain text')" />
        <s:Button label="Decrypt Text" click="decrypt({encryptedText})" />
    </mx:VBox>
</s:Application>
我将阅读一些有关RSA填充方案的书籍,看看是否有任何误解


谢谢

我删除了Webservices标签,并用公钥加密替换了它;因为这似乎是标记这个问题的更重要的方式。当用户有权访问密钥时,加密是无用的。您永远无法实现比SSL更安全的解决方案,因此您也可以使用它……感谢flextras@drkstr-用户拥有公钥,但不知道私钥,那么它怎么会毫无用处呢?我的web服务是通过https公开的,所以通过https可以实现一定程度的安全性。。。这是需要加密的监管把戏吗?我可以想象这样一种情况:客户机按照您想要的方式加密数据并发送到web服务器。但是web服务器没有解密密钥。其他一些机器偶尔会抓取数据并对其解密。这是没有用的,因为客户端加密只会对已经拥有数据的人隐藏数据@即使如此,运行加密服务器端也会更好。客户端加密唯一有意义的时间是当SSL不可用时,或者如果数据在发送到服务器之前需要本地存储(如离线模式)。由于客户机上已经存在未加密的数据,并且SSL将加密通过线路发送的任何内容,因此根本不需要运行任何类型的加密client-side.Jax,但是我是否提到我正在加密用户给定的输入?正在加密的数据不是用户的输入。某些信息应该进行端到端-客户端到服务器的加密。这个概念并不太复杂。在公钥密码学中,只要使用我的公钥进行加密,使用什么库/框架并不重要。我的问题是,如何在flex中加密,在c#中解密?我知道flex存在一些相关的安全问题,但我们不要深入讨论这些问题。@Rose没有实际需要在客户端加密数据。如果数据未加密地存在于客户端,那么它已经被泄露给whoe
private function _encrypt(op:Function, src:ByteArray, dst:ByteArray, length:uint, pad:Function, padType:int):void {
            // adjust pad if needed
            if (pad==null) pad = pkcs1pad;
RSA.Decrypt(DataToDecrypt, DoOAEPPadding); // DoOAEPPadding = false
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

    <fx:Script>
        <![CDATA[
            import com.hurlant.crypto.Crypto;
            import com.hurlant.crypto.rsa.RSAKey;
            import com.hurlant.crypto.symmetric.ICipher;
            import com.hurlant.crypto.symmetric.IPad;
            import com.hurlant.util.Hex;

            private var currentResult:String;
            private var encryptedText:String;
            private var decryptedText:String;

            private function encrypt(plainText:String):String {
                var rsa:RSAKey = RSAKey.parsePublicKey(getModulus(), getExponent());
                var data:ByteArray = Hex.toArray(Hex.fromString(plainText));  //returns byteArray of plainText
                var dst:ByteArray = new ByteArray;
                rsa.encrypt(data, dst, data.length);
                currentResult = Hex.fromArray(dst);
                encryptedText = currentResult;
                trace ("Cipher: " + currentResult);
                return currentResult;
            }

            private function getInput():ByteArray {
                return null;
            }

            private function getModulus():String {
                return "b6a7ca9002b4df39af1ed39251a5d"; //read this value from web service.
            }

            private function getExponent():String {
                return "011"; //read this value from web service.
            }

            //For debugging and testing purposes
            // private function decrypt(cipherText:String):String {
                // var rsa:RSAKey = RSAKey.parsePrivateKey(getModulus(), getExponent(), getPrivate(), getP(), getQ(), getDMP1(), getDMQ1(), getCoeff());
                // var data:ByteArray = Hex.toArray(cipherText);
                // var dst:ByteArray = new ByteArray;
                // rsa.decrypt(data, dst, data.length);
                // decryptedText = Hex.fromArray(dst);
                     //trace('decrypted : ' + decryptedText);
                // return Hex.toString(decryptedText);
            // }

        ]]>
    </fx:Script>

    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <mx:VBox >
        <s:Button label="Encrypt Text" click="encrypt('my plain text')" />
        <s:Button label="Decrypt Text" click="decrypt({encryptedText})" />
    </mx:VBox>
</s:Application>
 static public string RSADecrypt(string cipherText)
    {
        UnicodeEncoding ByteConverter = new UnicodeEncoding();
        byte[] DataToDecrypt = StringToByteArray(cipherText);
        bool DoOAEPPadding = false;
        try
        {
            byte[] decryptedData;
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                KeyInfo keyInfo = new KeyInfo();
                RSAParameters RSAKeyInfo = keyInfo.getKey();
                RSA.ImportParameters(RSAKeyInfo); 
                decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
            }
            byte[] paddedOutput = paddWithZeros(decryptedData); //to sync with as3crypto
            return (ByteConverter.GetString(paddedOutput));

        }catch (CryptographicException e)
        {
            //handle error
            return null;
        }
    }