zoukankan      html  css  js  c++  java
  • JAVA RSA私钥 加密(签名) 对应 C# RSA私钥 加密(签名)

    非对称密钥RSA算法加解密在C#和Java之间交互的问题,这两天看了很多其他人写的文章,碰到了几个问题,最终解决问题。

    参考地址:http://xw-z1985.iteye.com/blog/1837376

    需求目的:完成c#请求端RSA加密(签名)问题,客户端采用C#开发,服务器端采用Java开发。服务器端给客户端提供私钥,进行数据加密(签名),客户端加密(签名)后提数据提交给服务器,服务器用公钥对数据解密,进行验证。

    解决过程碰到的问题:

    1.JAVA 需要的 RSA私钥 格式和 C# 需要的 RSA私钥 不一致。 

    JAVA 需要是 PKCS8格式私钥:

    复制代码
    -----BEGIN PRIVATE KEY-----
    MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOwuOHH/OIRE+0if
    mEPYGuhYRTyKdd6VLFIsNqy/SO5xZitHfA7xEymJKnpEUGgDJKr5zbFbytnWs5Jj
    gen6TXkUh9LG/fhPGGHdUVB42pAHv5yzoyEaOnJxBAxd6UstoWTaEgbT6GUbzMr/
    Az25zuxw7c+skAlnUETVE5GL3tD7AgMBAAECgYEAxdNZODMctb3J9OSo93rV3vPA
    2prna87rVtDt4vg+MGsPtwSjZyiKcmoQCGWcK+MmHYgrwHkwihKKSv3KXZ9or3xQ
    2wNZGuTHLymWEzqfEfVb0igvxbe85EGwsaN3qSK62CK8vok/Bi+fZVa3UNCn0WFs
    lUS0qn+K3SECM9I1iwECQQD+2Pl2AJGQs2bRXSsnJk0FIwjpqdpGZFPlAUYaXkuT
    MqpwefP/bwwiuWqq9QIt2vAAKgy5T16tpPBcGpT6cvxBAkEA7T+i1gVwrXcozTuT
    9oCwkF2MGBaXkv3mN9H/Pfy/oIhTsgiDxX8t+0KapAEQogvCuAOq19JvGw5e91H2
    g0suOwJAJOMnCIuAhl9RTJCdxGbo0wuFKL0rGPFAq28JxJtNeRrmTK16QcjDCuun
    ouMf059TCdMMUG5Kl/u9xrcaRT4LgQJAZPiUYOnnzqvMHayhiGO0wXxOx2G2GMUe
    Wdtx+fu7wqLCnB6rlj5OX4U1M1+QqKbAtHg7Gadhye4P1Mp5U9+HSQJBANLVzcCX
    yAX2D12UPTPkhcNRaCRXFp3aJGMxI4iluUC+ukAdiapohqZ7vMQyWRq/tDyiwjir
    qMcg/AJIuQWmPyc=
    -----END PRIVATE KEY-----
    复制代码

    C# 需要的是 PKCS1 格式私钥:

    复制代码
    -----BEGIN RSA PRIVATE KEY-----
    MIICXQIBAAKBgQDsLjhx/ziERPtIn5hD2BroWEU8inXelSxSLDasv0jucWYrR3wO
    8RMpiSp6RFBoAySq+c2xW8rZ1rOSY4Hp+k15FIfSxv34Txhh3VFQeNqQB7+cs6Mh
    GjpycQQMXelLLaFk2hIG0+hlG8zK/wM9uc7scO3PrJAJZ1BE1RORi97Q+wIDAQAB
    AoGBAMXTWTgzHLW9yfTkqPd61d7zwNqa52vO61bQ7eL4PjBrD7cEo2coinJqEAhl
    nCvjJh2IK8B5MIoSikr9yl2faK98UNsDWRrkxy8plhM6nxH1W9IoL8W3vORBsLGj
    d6kiutgivL6JPwYvn2VWt1DQp9FhbJVEtKp/it0hAjPSNYsBAkEA/tj5dgCRkLNm
    0V0rJyZNBSMI6anaRmRT5QFGGl5LkzKqcHnz/28MIrlqqvUCLdrwACoMuU9eraTw
    XBqU+nL8QQJBAO0/otYFcK13KM07k/aAsJBdjBgWl5L95jfR/z38v6CIU7IIg8V/
    LftCmqQBEKILwrgDqtfSbxsOXvdR9oNLLjsCQCTjJwiLgIZfUUyQncRm6NMLhSi9
    KxjxQKtvCcSbTXka5kytekHIwwrrp6LjH9OfUwnTDFBuSpf7vca3GkU+C4ECQGT4
    lGDp586rzB2soYhjtMF8TsdhthjFHlnbcfn7u8Kiwpweq5Y+Tl+FNTNfkKimwLR4
    OxmnYcnuD9TKeVPfh0kCQQDS1c3Al8gF9g9dlD0z5IXDUWgkVxad2iRjMSOIpblA
    vrpAHYmqaIame7zEMlkav7Q8osI4q6jHIPwCSLkFpj8n
    -----END RSA PRIVATE KEY-----
    复制代码

    2.私钥格式之间的转换问题

    转换工具:openssl工具:http://www.slproweb.com/products/Win32OpenSSL.html

    转换参考地址: http://blog.csdn.net/hanzengyi/article/details/78029104

    java 代码 , 注意这里的私钥:是Pem私钥文件中去除头(-----BEGIN PRIVATE KEY-----)和尾(-----END PRIVATE KEY-----)以及换行符后的字符串

    复制代码
     1    /**
     2      * @data: 待加密的字符串
     3      * @privateKey: 私钥
     4      */
     5     public static String sign(byte[] data, String privateKey) throws Exception {
     6 
     7         byte[] keyBytes = new BASE64Decoder().decodeBuffer(privateKey);
     8         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
     9 
    10         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    11 
    12         PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
    13 
    14         Signature signature = Signature.getInstance("SHA1withRSA");
    15         signature.initSign(priKey);
    16         signature.update(data);
    17 
    18         return  byte2hex(signature.sign());
    19     }
    复制代码

     c# 代码,注意这里的私钥:是Pem私钥文件中去除头(-----BEGIN RSA PRIVATE KEY-----)和尾(-----END RSA PRIVATE KEY-----)以及换行符后的字符串

    复制代码
      1       /// <summary>
      2       /// 签名
      3       /// </summary>
      4       /// <param name="data">待加密的字符串</param>
      5       /// <param name="privateKey">私钥</param>
      6       /// <returns></returns>
      7      public static string Sign(string data, string privateKey)
      8         {
      9             RSACryptoServiceProvider rsaCsp = LoadCertificate(privateKey);
     10             byte[] dataBytes = Encoding.UTF8.GetBytes(data);
     11             byte[] signatureBytes = rsaCsp.SignData(dataBytes, "SHA1");
     12             return Hex_2To16(signatureBytes);
     13         }
     14 
     15         private static RSACryptoServiceProvider LoadCertificate(string privateKey)
     16         {
     17             byte[] res = res = Convert.FromBase64String(privateKey);
     18             try
     19             {
     20                 RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(res);
     21                 return rsa;
     22             }
     23             catch (Exception ex)
     24             {
     25             }
     26             return null;
     27         }
     28 
     29         private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
     30         {
     31             byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
     32 
     33             // --------- Set up stream to decode the asn.1 encoded RSA private key ------
     34             MemoryStream mem = new MemoryStream(privkey);
     35             BinaryReader binr = new BinaryReader(mem);  //wrap Memory Stream with BinaryReader for easy reading
     36             byte bt = 0;
     37             ushort twobytes = 0;
     38             int elems = 0;
     39             try
     40             {
     41                 twobytes = binr.ReadUInt16();
     42                 if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
     43                     binr.ReadByte();    //advance 1 byte
     44                 else if (twobytes == 0x8230)
     45                     binr.ReadInt16();    //advance 2 bytes
     46                 else
     47                     return null;
     48 
     49                 twobytes = binr.ReadUInt16();
     50                 if (twobytes != 0x0102) //version number
     51                     return null;
     52                 bt = binr.ReadByte();
     53                 if (bt != 0x00)
     54                     return null;
     55 
     56 
     57                 //------ all private key components are Integer sequences ----
     58                 elems = GetIntegerSize(binr);
     59                 MODULUS = binr.ReadBytes(elems);
     60 
     61                 elems = GetIntegerSize(binr);
     62                 E = binr.ReadBytes(elems);
     63 
     64                 elems = GetIntegerSize(binr);
     65                 D = binr.ReadBytes(elems);
     66 
     67                 elems = GetIntegerSize(binr);
     68                 P = binr.ReadBytes(elems);
     69 
     70                 elems = GetIntegerSize(binr);
     71                 Q = binr.ReadBytes(elems);
     72 
     73                 elems = GetIntegerSize(binr);
     74                 DP = binr.ReadBytes(elems);
     75 
     76                 elems = GetIntegerSize(binr);
     77                 DQ = binr.ReadBytes(elems);
     78 
     79                 elems = GetIntegerSize(binr);
     80                 IQ = binr.ReadBytes(elems);
     81 
     82 
     83                 // ------- create RSACryptoServiceProvider instance and initialize with public key -----
     84                 CspParameters CspParameters = new CspParameters();
     85                 CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
     86                 RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024, CspParameters);
     87                 RSAParameters RSAparams = new RSAParameters();
     88                 RSAparams.Modulus = MODULUS;
     89                 RSAparams.Exponent = E;
     90                 RSAparams.D = D;
     91                 RSAparams.P = P;
     92                 RSAparams.Q = Q;
     93                 RSAparams.DP = DP;
     94                 RSAparams.DQ = DQ;
     95                 RSAparams.InverseQ = IQ;
     96                 RSA.ImportParameters(RSAparams);
     97                 return RSA;
     98             }
     99             catch (Exception ex)
    100             {
    101                 return null;
    102             }
    103             finally
    104             {
    105                 binr.Close();
    106             }
    107         }
    108 
    109         private static int GetIntegerSize(BinaryReader binr)
    110         {
    111             byte bt = 0;
    112             byte lowbyte = 0x00;
    113             byte highbyte = 0x00;
    114             int count = 0;
    115             bt = binr.ReadByte();
    116             if (bt != 0x02)        //expect integer
    117                 return 0;
    118             bt = binr.ReadByte();
    119 
    120             if (bt == 0x81)
    121                 count = binr.ReadByte();    // data size in next byte
    122             else
    123                 if (bt == 0x82)
    124             {
    125                 highbyte = binr.ReadByte();    // data size in next 2 bytes
    126                 lowbyte = binr.ReadByte();
    127                 byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
    128                 count = BitConverter.ToInt32(modint, 0);
    129             }
    130             else
    131             {
    132                 count = bt;        // we already have the data size
    133             }
    134 
    135             while (binr.ReadByte() == 0x00)
    136             {    //remove high order zeros in data
    137                 count -= 1;
    138             }
    139             binr.BaseStream.Seek(-1, SeekOrigin.Current);        //last ReadByte wasn't a removed zero, so back up a byte
    140             return count;
    141         }
    142 
    143 
    144         /// <summary>
    145         /// 2进制转16进制
    146         /// </summary>
    147         public static String Hex_2To16(Byte[] bytes)
    148         {
    149             String hexString = String.Empty;
    150             Int32 iLength = 65535;
    151             if (bytes != null)
    152             {
    153                 StringBuilder strB = new StringBuilder();
    154 
    155                 if (bytes.Length < iLength)
    156                 {
    157                     iLength = bytes.Length;
    158                 }
    159 
    160                 for (int i = 0; i < iLength; i++)
    161                 {
    162                     strB.Append(bytes[i].ToString("X2"));
    163                 }
    164                 hexString = strB.ToString();
    165             }
    166             return hexString;
    167         }
    复制代码
  • 相关阅读:
    手把手教你利用create-nuxt-app脚手架创建NuxtJS应用
    初识NuxtJS
    webpack打包Vue应用程序流程
    用选择器代替表格列的筛选功能
    Element-UI
    Spectral Bounds for Sparse PCA: Exact and Greedy Algorithms[贪婪算法选特征]
    Sparse Principal Component Analysis via Rotation and Truncation
    Generalized Power Method for Sparse Principal Component Analysis
    Sparse Principal Component Analysis via Regularized Low Rank Matrix Approximation(Adjusted Variance)
    Truncated Power Method for Sparse Eigenvalue Problems
  • 原文地址:https://www.cnblogs.com/Alex80/p/9204840.html
Copyright © 2011-2022 走看看