如何使用c#.net中的RijndaelManage算法加密一个项目中的对象和我们必须在另一个项目中解密的同一个对象 [英] How to Encrypt object in one project and same object we have to decrypt in another project using RijndaelManage algorithm in c#.net

查看:47
本文介绍了如何使用c#.net中的RijndaelManage算法加密一个项目中的对象和我们必须在另一个项目中解密的同一个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨朋友们,



我是Cryptography的新手。我想加密Windows应用程序中的对象和我们使用RijndaelManage算法在WCF服务中解密的相同对象。在这里,我们可以在Windows应用程序中加密和解密。但无法在wcf服务中解密。



我收到的错误是:填充无效且无法删除 ..



我在Windows应用程序中编写的内容:

  static  < span class =code-keyword> byte  [] EncryptStringToBytes( string  plainText, byte  []键,字节 [] IV)
{
// 检查参数。
if (plainText == null || plainText.Length < = 0
throw new ArgumentNullException( 明文);
if (Key == null || Key.Length < = 0
throw new ArgumentNullException( Key);
if (IV == null || IV.Length < = 0
throw new ArgumentNullException( IV);
byte []已加密;
// 创建RijndaelManaged对象
// 使用指定的密钥和IV。
使用(RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;

// 创建解密器以执行流转换。
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key,rijAlg.IV);

// 创建用于加密的流。
< span class =code-keyword> using
(MemoryStream msEncrypt = new MemoryStream())
{
使用(CryptoStream csEncrypt = new CryptoStream(msEncrypt,encryptor,CryptoStreamMode.Write))
{
使用(StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{

// 将所有数据写入流中。
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}


// 从内存流中返回加密的字节。
return 加密;

}





我在WCF服务中写的内容:



 静态  string  DecryptStringFromBytes( byte  [] cipherText, byte  [] Key, byte  [] IV)
{
// 检查参数。
if (cipherText == null || cipherText.Length < = 0
throw new ArgumentNullException( cipherText);
if (Key == null || Key.Length < = 0
throw new ArgumentNullException( Key);
if (IV == null || IV.Length < = 0
throw new ArgumentNullException( IV);

// 声明用于保存的字符串
// 解密文本。
string plaintext = null ;

// 创建RijndaelManaged对象
// 使用指定的密钥和IV。
使用(RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;

// 创建解密器以执行流转换。
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key,rijAlg.IV);

// 创建用于解密的流。
< span class =code-keyword> using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
使用(CryptoStream csDecrypt = new CryptoStream(msDecrypt,decryptor,CryptoStreamMode.Read))
{
使用(StreamReader srDecrypt = new StreamReader(csDecrypt))
{

// 从解密流中读取解密的字节
// 并将它们置于一个strin中g。
plaintext = srDecrypt.ReadToEnd();
}
}
}

}

返回明文;

}







我的服务方法是:objservice.registeremployee(plainText ,key,iv);





注意:有没有其他方法可以解决这个问题。因为这些功能将在这个星期一上线。

请帮助我任何一个。

解决方案

尝试在将它们转换为数组之前刷新你的流 - 你很可能有数据等待在转移之前填写你没有得到的加密块。

这是我使用的方法:

  ///   <  摘要 >  
/// 将传入流加密到传出流。
/// < / summary >
/// < 备注 < span class =code-summarycomment>> 我们不会关闭sIn或sOut。
/// 由于这些可能是MemoryStreams,关闭它们会丢弃数据!
/// 最好解密到内存,而不是文件!
/// 我们不使用大于int full的文件。
/// 修改此项以阻止I / O $相当容易b $ b /// 我们使输出大于它需要刷新所有真实 data
/// 到输出。
/// (这不是必需的,但在解密到MemoryStream时,你有
/// 关闭它以获取最后一个块。不要问我为什么 - 问MS。)< / remarks >
/// < param name =sIn > 要加密的未加密数据< / param >
/// < param name =sOut > 加密输出。请注意,这将包括cyrptoheader块
/// 因此将大于输入。< / param >
public void 加密(Stream sIn,Stream sOut)
{
string Routine = 加密:< /跨度>;
if (key == null
{
throw new CryptoHelperException(Routine,EX_CRYPTO_NOKEY);
}
if (sIn.Length > int .MaxValue)
{
throw new CryptoHelperException(Routine,EX_CRYPTO_TOOBIG);
}
sOut.Write(CreateBlockHeader(sIn), 0 ,encAlg.BlockSize);
int inputLength;
byte [] abIn;
switch ((CryptoSecurity)架构)
{
case CryptoSecurity .NoEncrypt:
inputLength =( int )sIn.Length;
abIn = new byte [inputLength];
sIn.Read(abIn, 0 ,inputLength);
sOut.Write(abIn, 0 ,inputLength);
break ;
case CryptoSecurity.TripleDES:
CryptoStream encrypt = new CryptoStream(sOut,encAlg .CreateEncryptor(),CryptoStreamMode.Write);
inputLength =( int )sIn.Length + encAlg.BlockSize; // 太大了!
abIn = new byte [inputLength];
sIn.Read(abIn, 0 ,inputLength);
encrypt.Write(abIn, 0 ,inputLength);
encrypt.FlushFinalBlock();
key.Reset();
break ;
默认
throw new CryptoHelperException(Routine,EX_CRYPTO_BADSCHEMA);
}
if (sIn.CanSeek)
{
sIn.Seek( 0 ,SeekOrigin.Begin);
}
if (sOut.CanSeek)
{
sOut.Seek( 0 ,SeekOrigin.Begin);
}
}





它使用AES而不是Rijndael,但原理是一样的。


Hi Friends,

I am new for Cryptography. I want encrypt the object in windows application and same object we have decrypt in WCF service using RijndaelManage Algorithm. Here we can able to encrypt and decrypt in windows application. But unable to decrypt in wcf service.

I got error is :Padding is invalid and cannot be removed ..

What i have written in Windows application :

static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
       {
           // Check arguments.
           if (plainText == null || plainText.Length <= 0)
               throw new ArgumentNullException("plainText");
           if (Key == null || Key.Length <= 0)
               throw new ArgumentNullException("Key");
           if (IV == null || IV.Length <= 0)
               throw new ArgumentNullException("IV");
           byte[] encrypted;
           // Create an RijndaelManaged object
           // with the specified key and IV.
           using (RijndaelManaged rijAlg = new RijndaelManaged())
           {
               rijAlg.Key = Key;
               rijAlg.IV = IV;

               // Create a decrytor to perform the stream transform.
               ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

               // Create the streams used for encryption.
               using (MemoryStream msEncrypt = new MemoryStream())
               {
                   using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                   {
                       using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                       {

                           //Write all data to the stream.
                           swEncrypt.Write(plainText);
                       }
                       encrypted = msEncrypt.ToArray();
                   }
               }
           }


           // Return the encrypted bytes from the memory stream.
           return encrypted;

       }



What i have written in WCF Service :

static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
        {
            // Check arguments.
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");

            // Declare the string used to hold
            // the decrypted text.
            string plaintext = null;

            // Create an RijndaelManaged object
            // with the specified key and IV.
            using (RijndaelManaged rijAlg = new RijndaelManaged())
            {
                rijAlg.Key = Key;
                rijAlg.IV = IV;

                // Create a decrytor to perform the stream transform.
                ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

                // Create the streams used for decryption.
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {

                            // Read the decrypted bytes from the decrypting stream
                            // and place them in a string.
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }

            }

            return plaintext;

        }




My service method is : objservice.registeremployee(plainText,key,iv);


Note: Is there any other way to resolve that issue. Beacause these functionality will go for live on this monday.
Kindly help me any one.

解决方案

Try flushing your streams before converting them to arrays - it's quite possible you have data "waiting" to fill an encryption block that you aren't getting before you transfer it.
Here is the method I use:

/// <summary>
/// Encrypts an incoming stream to the outgoing stream.
/// </summary>
/// <remarks>We do NOT close sIn or sOut.
/// Since these could be MemoryStreams, closing them would throw away the data!
/// It is good practice to decrypt to memory, not file!
/// We don't work with files bigger than an int full. It would be fairly easy to
/// modify this to block the I/O
/// We make the output bigger than it needs to be to flush  all the "real" data
/// to the output.
/// (This should not be necessary, but when decrypting to a MemoryStream you have
/// to close it to get the last block. Don't ask me why - ask MS.)</remarks>
/// <param name="sIn">Unencrypted data to encrypt</param>
/// <param name="sOut">Encrypted output. Note this will include a cyrptoheader block
/// and so will be larger than the input.</param>
public void Encrypt(Stream sIn, Stream sOut)
    {
    string Routine = "Encrypt: ";
    if (key == null)
        {
        throw new CryptoHelperException(Routine, EX_CRYPTO_NOKEY);
        }
    if (sIn.Length > int.MaxValue)
        {
        throw new CryptoHelperException(Routine, EX_CRYPTO_TOOBIG);
        }
    sOut.Write(CreateBlockHeader(sIn), 0, encAlg.BlockSize);
    int inputLength;
    byte[] abIn;
    switch ((CryptoSecurity) schema )
        {
        case CryptoSecurity.NoEncrypt:
            inputLength = (int) sIn.Length;
            abIn = new byte[inputLength];
            sIn.Read(abIn, 0, inputLength);
            sOut.Write(abIn, 0, inputLength);
            break;
        case CryptoSecurity.TripleDES:
            CryptoStream encrypt = new CryptoStream(sOut, encAlg.CreateEncryptor(), CryptoStreamMode.Write);
            inputLength = (int)sIn.Length + encAlg.BlockSize; // Make it too big!
            abIn = new byte[inputLength];
            sIn.Read(abIn, 0, inputLength);
            encrypt.Write(abIn, 0, inputLength);
            encrypt.FlushFinalBlock();
            key.Reset();
            break;
        default:
            throw new CryptoHelperException(Routine, EX_CRYPTO_BADSCHEMA);
        }
    if (sIn.CanSeek)
        {
        sIn.Seek(0, SeekOrigin.Begin);
        }
    if (sOut.CanSeek)
        {
        sOut.Seek(0, SeekOrigin.Begin);
        }
    }



It uses AES rather than Rijndael but the principle is the same.


这篇关于如何使用c#.net中的RijndaelManage算法加密一个项目中的对象和我们必须在另一个项目中解密的同一个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆