一个实用的基于RSACryptoServiceProvider的Helper类

RSACryptoServiceProvider提供的加解密算法实在够难用的, 无奈自己的项目需要使用, 网上也没找到能做到自动分段加解密的封装, 无奈自己写一个吧. 在此提供源代码, 希望能对为此苦恼的朋友有所帮助.

/*  Goal: 
 *     .NET内置的RSA算法太难用, 这里要实现一个自动分段加解密的封装.
 * 
 * Design describe: 
 *     本着实用的原则, 只提供产生密钥对的方法, 和加解密方法.
 * 
 * Write by:
 *     WangYiBo, 2008/5/20
 *     
 * Changing record:
 *     
 
*/


using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

using  System.Security.Cryptography;

namespace  PublicClassLibrary.Definition
{
    
public   class  RSAKeyPair
    {
        
public   readonly   string  PrivateKey;
        
public   readonly   string  PublicKey;

        
private  RSAKeyPair()
        { }

        
internal  RSAKeyPair( string  privateKey,  string  publicKey)
        {
            PrivateKey 
=  privateKey;
            PublicKey 
=  publicKey;
        }
    }

    
static   public   class  RSAEncryption
    {
        
// 微软的RSA算法需要填充随机数, 此数值受Encrypt方法中参数fOAEP的影响
         const   int  MinRandomCount_fOAEPIsTure  =   11 ;
        
const   int  MinRandomCount_fOAEPIsFalse  =   41 ;

        
static   public  RSAKeyPair CreatRSAKey( int  dwKeySize)
        {
            RSACryptoServiceProvider rsa 
=   new  RSACryptoServiceProvider(dwKeySize);

            
return   new  RSAKeyPair(rsa.ToXmlString( true ), rsa.ToXmlString( false ));
        }


        
static   public   byte [] RSAEncrypt( this   byte [] data,  string  publicKey,  bool  fOAEP)
        {
            
#region  因为不同的RSA加密位数会导致不同的buffer大小, 此步推算.
            
int  bfSize  =   1 , length  =  publicKey.Length  -   67 ;

            
int  count  =   0 ;
            
while  (length  >   1 )
            {
                length 
>>=   1 ;
                count
++ ;
            }

            bfSize 
<<=  count;
            
#endregion


            
#region  推算每次运算实际可以允许的最大有效数量
            
int  eCount;
            
if  (fOAEP)
            {
                eCount 
=  bfSize  -  MinRandomCount_fOAEPIsFalse;
            }
            
else
            {
                eCount 
=  bfSize  -  MinRandomCount_fOAEPIsTure;
            }
            
#endregion



            
#region  分段加密.
            
int  resultBlockCount  =  (data.Length  -   1 /  eCount  +   1 ;

            
byte [] bfBytes;
            
byte [] oBytes1  =   new   byte [eCount];
            
byte [] oBytes2  =   new   byte [data.Length  %  eCount];
            
byte [] result  =   new   byte [resultBlockCount  *  bfSize];

            RSACryptoServiceProvider rsa 
=   new  RSACryptoServiceProvider();
            rsa.FromXmlString(publicKey);

            
for  ( int  bc  =   0 ; bc  <  resultBlockCount  -   1 ; bc ++ )
            {
                
for  ( int  i  =   0 ; i  <  oBytes1.Length; i ++ )
                {
                    oBytes1[i] 
=  data[bc  *  oBytes1.Length  +  i];
                }
                bfBytes 
=  rsa.Encrypt(oBytes1, fOAEP);
                
for  ( int  j  =   0 ; j  <  bfBytes.Length; j ++ )
                {
                    result[bc 
*  bfBytes.Length  +  j]  =  bfBytes[j];
                }
            }


            
for  ( int  i  =   0 ; i  <  oBytes2.Length; i ++ )
            {
                oBytes2[i] 
=  data[(resultBlockCount  -   1 *  oBytes1.Length  +  i];
            }
            bfBytes 
=  rsa.Encrypt(oBytes2, fOAEP);
            
for  ( int  j  =   0 ; j  <  bfBytes.Length; j ++ )
            {
                result[(resultBlockCount 
-   1 * bfBytes.Length  +  j]  =  bfBytes[j];
            }
            
#endregion

            
return  result;
        }


        
static   public   byte [] RSADecrypt( this   byte [] data,  string  privateKey,  bool  fOAEP)
        {
            
#region  推算bufferSize
            
int  bfSize  =   1 , length  =  (privateKey.Length  -   127 /   4 ;

            
int  count  =   0 ;
            
while  (length  >   1 )
            {
                length 
>>=   1 ;
                count
++ ;
            }

            bfSize 
<<=  count;
            
#endregion



            
#region  分段解密
            
int  resultBlockCount  =  (data.Length  -   1 /  bfSize  +   1 ;

            
byte [] bfBytes;
            
byte [] oBytes  =   new   byte [bfSize];
            
byte [] result  =   new   byte [data.Length];

            RSACryptoServiceProvider rsa 
=   new  RSACryptoServiceProvider();
            rsa.FromXmlString(privateKey);

            
int  pbfBytesLength  =   0 ;
            
for  ( int  bc  =   0 ; bc  <  resultBlockCount; bc ++ )
            {
                
for  ( int  i  =   0 ; i  <  oBytes.Length; i ++ )
                {
                    oBytes[i] 
=  data[bc  *  oBytes.Length  +  i];
                }
                bfBytes 
=  rsa.Decrypt(oBytes, fOAEP);

                
for  ( int  j  =   0 ; j  <  bfBytes.Length; j ++ )
                {
                    result[pbfBytesLength 
+  j]  =  bfBytes[j];
                }
                pbfBytesLength 
+=  bfBytes.Length;
            }

            Array.Resize
< byte > ( ref  result, pbfBytesLength);
            
#endregion


            
return  result;
        }
    }
}

你可能感兴趣的:(Provider)