zoukankan      html  css  js  c++  java
  • .net平台的RSA实现以及与Delphi之间的互操作性

    .net平台下面的RSA算法实现是RSACryptoServiceProvider,如果安装了 Microsoft Enhanced Cryptographic Provider,则 RSACryptoServiceProvider 支持长度从 384 位至 16384 位(增量为 8 位)的密钥。如果安装了 Microsoft Base Cryptographic Provider,则支持长度从 384 位至 512 位(增量为 8 位)的密钥。
       目前该算法支持的填充Padding算法为PKCS#1 1.5和OAEPPadding,而签名算法目前仅支持SHA1withRSA算法,其他的好像没有提供,或许需要安装其他provider,目前第三方的provider可以使用Bouncy Castle的C#实现
    http://www.bouncycastle.org/csharp/,使用Bouncy Castle的包可以实现
    RIPEMD128、RIPEMD160、RIPEMD256、SHA-1、SHA-224、SHA-256、SHA-384、SHA-512、MD2,MD4,MD5等HASH算法与RSA的集成签名算法。
    为了更好的处理BigInteger运算的问题,在本文中用到了
    http://www.codeproject.com/csharp/biginteger.asp提供的BigInteger.cs用来处理大数运算的问题,用来验证的DLL实用delphi实现的,当然也可以用java来验证,效果相同,该DLL的代码在下面专题中作详细讲解。
       具体源代码如下:

      1using System.Text.RegularExpressions;
      2using System.Text;
      3using System.IO;
      4using System.Net;
      5using System.Xml;
      6using System.Runtime.InteropServices;
      7using System;
      8using System.Security;
      9using System.Security.Cryptography;
     10/*
     11    RSA Keyinfo:
     12    ---------------------------------------------------------------------
     13    可以采用java或者.net生成下面参数信息
     14    加密位:1024bits
     15    >>>PrivateKey:
     16    modulus:123410773237385713572440712840019405878257600213906351775134402766524785605776353635515879438375969303333340691224323217379791619946464100287854264933660919378485000299257054039555887477610831829409144592603086784397675690934246422666689022312589317493002336070775714030955737435316659994026756956753416169929
     17    public exponent:65537
     18    private exponent:102299672961750099570264341757280532275542401837445663770632643616494888426681205847125069294737520917541038900032845310395266178574112466427178094767628391398378924953787043659322148498169017989730953803803890989295625028193153480552247210183981959942844345362118479513739632952091865360095551345350474614233
     19    prime p:12794390226544301614076650435602993036558056678553112540698297249963365434628505393116653422818365344228379828231764392521731584684435248093787027949139091
     20    prime q:9645694015283940797244851561543569992525098416055322825220116046655435860727361740896753161534492415500799272063647633894112205918420307541634544631799219
     21    prime exponent p:1529969882744521289493243655703200580244831014386083326692594344385048063096931454992679141166478923397741927672190328275520857365639547725880173612423563
     22    prime exponent q:769453717928871362558494956494038236735297839680443531596667023084892788499361386413907037681040120057954721673997128797449053397950796768659923391901465
     23    crt coefficient:12583540851660819630796910273258143748946857763306703439274571717196507402536398234616014735603915981141807543055250658251670340810611251684169356826070785
     24    >>>PublicKey:
     25    modulus:123410773237385713572440712840019405878257600213906351775134402766524785605776353635515879438375969303333340691224323217379791619946464100287854264933660919378485000299257054039555887477610831829409144592603086784397675690934246422666689022312589317493002336070775714030955737435316659994026756956753416169929
     26    public exponent:65537
     27    */

     28
     29public class RSATest
     30{
     31    [DllImport("cmipcrypt.dll")]
     32    public static extern String Cmip_Encrypt(String text,String exp,String module);
     33
     34    [DllImport("cmipcrypt.dll")]
     35    public static extern String Cmip_Decrypt(String etext,String d,String module);
     36
     37    [DllImport("cmipcrypt.dll")]
     38    public static extern String Cmip_SignData(String text,String d,String module,String alg);
     39
     40    [DllImport("cmipcrypt.dll")]
     41    public static extern String Cmip_VerifyData(String text,String signtext,String r,String module);
     42
     43    [DllImport("cmipcrypt.dll")]
     44    public static extern String Cmip_ComputeHash(String text,String alg);
     45
     46    private String p,q,e,n,d,dp,dq,crt;
     47    private RSAParameters param;
     48
     49    public void init(){
     50        p="12794390226544301614076650435602993036558056678553112540698297249963365434628505393116653422818365344228379828231764392521731584684435248093787027949139091";
     51        q="9645694015283940797244851561543569992525098416055322825220116046655435860727361740896753161534492415500799272063647633894112205918420307541634544631799219";
     52        e="65537";
     53        n="123410773237385713572440712840019405878257600213906351775134402766524785605776353635515879438375969303333340691224323217379791619946464100287854264933660919378485000299257054039555887477610831829409144592603086784397675690934246422666689022312589317493002336070775714030955737435316659994026756956753416169929";
     54        d="102299672961750099570264341757280532275542401837445663770632643616494888426681205847125069294737520917541038900032845310395266178574112466427178094767628391398378924953787043659322148498169017989730953803803890989295625028193153480552247210183981959942844345362118479513739632952091865360095551345350474614233";
     55        dp="1529969882744521289493243655703200580244831014386083326692594344385048063096931454992679141166478923397741927672190328275520857365639547725880173612423563";
     56        dq="769453717928871362558494956494038236735297839680443531596667023084892788499361386413907037681040120057954721673997128797449053397950796768659923391901465";
     57        crt="12583540851660819630796910273258143748946857763306703439274571717196507402536398234616014735603915981141807543055250658251670340810611251684169356826070785";
     58
     59        param=new RSAParameters();
     60        byte[] bdata=GetBytes(e);
     61        param.Exponent=bdata;
     62        param.P=GetBytes(p);
     63        param.Q=GetBytes(q);
     64        param.Modulus=GetBytes(n);
     65        param.D=GetBytes(d);
     66        param.DP=GetBytes(dp);
     67        param.DQ=GetBytes(dq);
     68        param.InverseQ=GetBytes(crt);
     69    }

     70
     71    public static void Main(String[] args)
     72    {
     73        if(args.Length<2){
     74            Console.WriteLine(" RSATest.exe [text明文] [hash算法]。");
     75            return;
     76        }

     77        RSATest rsa=new RSATest();
     78        rsa.init();
     79        rsa.DelphiDllTest(args[0],args[1]);
     80        rsa.DotnetRSATest(args[0],args[1]);
     81        rsa.InteropTest(args[0],args[1]);
     82        
     83
     84
     85    }

     86    
     87    public void DelphiDllTest(String text,String alg){
     88        String res=Cmip_Encrypt(text,e,n);
     89        Console.WriteLine("=====================Dll调用RSA测试=====================");
     90        Console.WriteLine(" 1.明文:"+text);
     91        //加密
     92        Console.WriteLine(" 2.RSA加密:"+res);    
     93        res=Cmip_Decrypt(res,d,n);
     94        Console.WriteLine(" 3.RSA解密:"+res);    
     95        //签名
     96        String signdata=Cmip_SignData(text,d,n,alg);
     97        Console.WriteLine(" 4.对明文采用"+alg.Trim()+"withRSA的签名算法,签名数据为: "+signdata);    
     98        Console.WriteLine(" 5.RSA验证签名:"+Cmip_VerifyData(text,signdata,e,n));    
     99
    100        Console.WriteLine(" 6.采用HASH算法"+alg+"计算明文的结果:"+Cmip_ComputeHash(text,alg));
    101    }

    102    //.net只实现了SHA1的rsa签名算法
    103    public void  DotnetRSATest(String text,String alg){
    104        Console.WriteLine(" =========.net RSACryptoServiceProvider调用RSA测试=========");
    105        
    106        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    107        rsa.ImportParameters(param);
    108        RSAParameters param1=rsa.ExportParameters(true);
    109
    110        Console.WriteLine("1.明文:"+text);
    111        byte[] data=Encoding.Default.GetBytes(text);
    112        byte[] endata=rsa.Encrypt(data,false);
    113        Console.WriteLine(" 2.publicKey加密后的数据:"+Convert.ToBase64String(endata));
    114        byte[] dedata=rsa.Decrypt(endata,false);
    115        Console.WriteLine(" 3.privateKey解密后的数据:"+Encoding.Default.GetString(dedata));
    116        //签名
    117        HashAlgorithm hashalg=null;
    118        switch(alg.ToUpper()){
    119            case "MD5":
    120                hashalg=new MD5CryptoServiceProvider();
    121                break;
    122            case "SHA1":
    123                hashalg=new SHA1CryptoServiceProvider (); ;
    124                break;
    125            case "SHA256":
    126                hashalg=new SHA256Managed();
    127                break;
    128            case "SHA384":
    129                hashalg=new SHA384Managed();
    130                break;
    131            case "SHA512":
    132                hashalg=new SHA512Managed();
    133                break;
    134            default:
    135                throw new Exception("不支持的HASH算法:"+alg);
    136        }

    137        try{
    138            byte[] signdata=rsa.SignData(data,hashalg);
    139            Console.WriteLine(" 4.对明文采用"+alg.Trim()+"withRSA的签名算法,签名数据为: "+Convert.ToBase64String(signdata));    
    140            Console.WriteLine(" 5.RSA验证签名:"+rsa.VerifyData(data,hashalg,signdata));    
    141        }
    catch(CryptographicException ex){
    142            Console.WriteLine(" ===================================");
    143            Console.WriteLine("!!!指定的HASH算法在.net中可能未实现!:"+ex.Message+" .net可用算法"+rsa.SignatureAlgorithm);
    144            Console.WriteLine("===================================");
    145        }

    146        byte[] hash=hashalg.ComputeHash(data);
    147        Console.WriteLine(" 6.采用HASH算法"+alg+"计算明文的结果:"+ConvByteArrayToHex(hash));
    148
    149
    150        String res=Cmip_Decrypt(Convert.ToBase64String(endata),d,n);
    151        Console.WriteLine(" "+res);
    152        Console.WriteLine(Encoding.Default.ToString());
    153
    154    }

    155    //dll加密,.net解密
    156    //dll签名,.net验证
    157    public void InteropTest(String text,String alg){
    158        String res=Cmip_Encrypt(text,e,n);
    159        Console.WriteLine(" =====================跨语言平台调用RSA测试=====================");
    160        Console.WriteLine(" 1.明文:"+text);
    161        //加密
    162        Console.WriteLine(" 2.DLL RSA加密:"+res);    
    163        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    164        rsa.ImportParameters(param);
    165        byte[] txdata=rsa.Decrypt(Convert.FromBase64String(res),false);
    166
    167        Console.WriteLine(" 3.RSACryptoServiceProvider RSA解密:"+Encoding.Default.GetString(txdata));    
    168        //dll签名,.net验证
    169        String signdata=Cmip_SignData(text,d,n,alg);
    170        Console.WriteLine(" 4.DLL 对明文采用"+alg.Trim()+"withRSA的签名算法,签名数据为: "+signdata);    
    171        //签名
    172        HashAlgorithm hashalg=null;
    173        switch(alg.ToUpper()){
    174            case "MD5":
    175                hashalg=new MD5CryptoServiceProvider();
    176                break;
    177            case "SHA1":
    178                hashalg=new SHA1CryptoServiceProvider (); ;
    179                break;
    180            case "SHA256":
    181                hashalg=new SHA256Managed();
    182                break;
    183            case "SHA384":
    184                hashalg=new SHA384Managed();
    185                break;
    186            case "SHA512":
    187                hashalg=new SHA512Managed();
    188                break;
    189            default:
    190                throw new Exception("不支持的HASH算法:"+alg);
    191        }

    192        try{
    193            Console.WriteLine(" 5.RSACryptoServiceProvider RSA验证签名:"+rsa.VerifyData(Encoding.Default.GetBytes(text),hashalg,Convert.FromBase64String(signdata)));    
    194        }
    catch(CryptographicException ex){
    195            Console.WriteLine(" ===================================");
    196            Console.WriteLine("!!!指定的HASH算法在.net中可能未实现!:"+ex.Message+" .net可用算法"+rsa.SignatureAlgorithm);
    197            Console.WriteLine("===================================");
    198        }

    199    }

    200
    201    public static byte[] GetBytes(String num){
    202        BigInteger n=new BigInteger(num,10);
    203        String s=n.ToString(2);
    204        if(s.Length%8>0){
    205            s=new String('0',8-s.Length%8)+s;
    206        }

    207        byte[] data=new byte[s.Length/8];
    208        String ocetstr;
    209        for(int i=0;i<data.Length;i++){
    210            ocetstr=s.Substring(8*i,8);
    211            data[i]=Convert.ToByte(ocetstr , 2 ) ;
    212        }

    213        return data;
    214    }

    215
    216    public String ConvByteArrayToHex(byte[] data){
    217        String s="";
    218        for(int i=0;i<data.Length;i++){
    219            s+=Convert.ToString(data[i],16);
    220        }

    221        return s.ToUpper();
    222    }

    223
    224
    225}


    运行结果如下:

    d:>rsatest hello加密 sha1
    =====================Dll调用RSA测试=====================

    1.明文:hello加密

    2.RSA加密:A/0ZWckK9C6JyTk8NmwESVSI/N8OyQ7nYBEK8cpzo30nHj+Pb0WfvQ+lFa38Xk3cd+d8ueysTSc7tqr4Wjk831d0MexAC2yJ4SkqLWfKnhuU0OxF6d4s8UpegvuMBy1KWpzovbFGa3HUGRmMVbu4GqPDdzkvFmfWzGArXXiDpVw=

    3.RSA解密:hello加密

    4.对明文采用sha1withRSA的签名算法,签名数据为:
    iz5J3e3H9NhHhs0qV7GlAODemWR8k7lhubqQJ+rdWl00ekOXu1EgULmeqalfip/3G98+X2eQyJ37bTjSpZ2oW4sIDYDJ3tHaaqooLtS6Iz8GWND+52YDZFLX8t+Yure5+tn2e1C9R181RnZfKt9dKQ2vpw0H6KqXNRwbmQJLynY=

    5.RSA验证签名:true

    6.采用HASH算法sha1计算明文的结果:C3F118FF24E166AC977EC9C3D69A5AF8B7C78F8B

    =========.net RSACryptoServiceProvider调用RSA测试=========

    1.明文:hello加密

    2.publicKey加密后的数据:NrW/Uwjd72SduBgQkOFjjtEibTX/+WOCV0/oIFMiEln5uhLZ5OaH6cyWPEXBEwjZIiUY78dmdk8BW6SmiDArNwFePf/tM7KCAcSU9Zz3PGl07ZDmvT1P8F24caKaX9+fGwy72mOtoBhFnKh18oOjq4wZ06e1g8IQQQco9W+kHgU=

    3.privateKey解密后的数据:hello加密

    4.对明文采用sha1withRSA的签名算法,签名数据为:
    iz5J3e3H9NhHhs0qV7GlAODemWR8k7lhubqQJ+rdWl00ekOXu1EgULmeqalfip/3G98+X2eQyJ37bTjSpZ2oW4sIDYDJ3tHaaqooLtS6Iz8GWND+52YDZFLX8t+Yure5+tn2e1C9R181RnZfKt9dKQ2vpw0H6KqXNRwbmQJLynY=

    5.RSA验证签名:True

    6.采用HASH算法sha1计算明文的结果:C3F118FF24E166AC977EC9C3D69A5AF8B7C78F8B

    hello加密

    System.Text.DBCSCodePageEncoding

    =====================跨语言平台调用RSA测试=====================

    1.明文:hello加密

    2.DLL RSA加密:P/AP7Iwv7pYxh+T1a/PZ4UBCZABu7zPpNt65W5ncNfo8eVQbH8jlH/Jv+fGa0x4CCmRUaTA0O1HeO4LowRpFyPJkwLxQAsMedvfRcQ7Ro2Hggoz5uwRG6QZ2go0Io0KAOGhcV4efKHFG2xro4jYX2O2hWyHTeMldDQPxt98z2co=

    3.RSACryptoServiceProvider RSA解密:hello加密

    4.DLL 对明文采用sha1withRSA的签名算法,签名数据为:
    iz5J3e3H9NhHhs0qV7GlAODemWR8k7lhubqQJ+rdWl00ekOXu1EgULmeqalfip/3G98+X2eQyJ37bTjSpZ2oW4sIDYDJ3tHaaqooLtS6Iz8GWND+52YDZFLX8t+Yure5+tn2e1C9R181RnZfKt9dKQ2vpw0H6KqXNRwbmQJLynY=

    5.RSACryptoServiceProvider RSA验证签名:True


    有关程序下载:
    http://files.cnblogs.com/midea0978/rsa.net.rar

    附注:对于这个RSA的跨平台技术,已经是07年研究的结果,后来就没怎么深入了,目前本人已经在一个项目中使用这方面该技术,应用在delphi,powerbuilder,J2EE复合环境中。对于这方面的详细源代码或者技术支持感兴趣的话,如能提供一定报酬的基础上,可使用站内消息联系博主转让!

    当然如果免费使用的话,附件中的cmipcrypt.dll是没有任何限制,随便使用。

  • 相关阅读:
    Android 修改应用程序字体
    Activity A 跳转到Activity B 生命周期
    Android调用系统设置
    最近遇到adb connection 问题,总结一下
    今日写一篇散文 Textview settext 方法不能放入 int 参数 不然报错!
    计时线程Runnable和Handler的结合
    JMF 下载安装与测试 测试成功
    基本数据类型的介绍及转换,基本数据类型与字符串之间转换,字符串与字符数组之间转换以及字符串与字节数组之间转换
    超实用的Eclipse快捷键大全(解密为什么他们的代码写的又快又好~)
    JDK的下载、安装及Eclipse安装详细教程(内附:网盘win64版JDK安装包)
  • 原文地址:https://www.cnblogs.com/adylee/p/3611772.html
Copyright © 2011-2022 走看看