zoukankan      html  css  js  c++  java
  • 一个实用的基于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;
            }
        }
    }
  • 相关阅读:
    ckeditor+粘贴word
    java+批量下载大文件
    链接批量下载文件
    java+大文件上传解决方案
    php+提高大文件上传速度
    富文本粘贴word文档内容图片处理
    软件开发工具(三)——理论与开发过程
    c结构体里的数组与指针
    Java解析Property文件
    怎样高速编译mediatekoperator以下代码
  • 原文地址:https://www.cnblogs.com/WYB/p/1225704.html
Copyright © 2011-2022 走看看