找回密码  加入

AUTOIT CN

搜索
查看: 330|回复: 6

[效率算法] RSA算法C#转AU3时PEM格式私钥的转化

[复制链接]
发表于 2018-12-24 18:03:45 | 显示全部楼层 |阅读模式
本帖最后由 xyx115 于 2018-12-25 09:14 编辑

下面的代码是一段C#关于RSA的加解密的代码。但其中的私钥、公钥,难以理解,怎么转化成AU3的私钥、公钥、并且被AU3的代码正常解读。这几天看了前辈们写的_RSA_crypt_汉化的例子。觉得写的很好,但新手理解能力有限。
在网上百度了很多资料,都没有相关的转换方法。请各位高手帮忙看看。

  1. <blockquote>    #region RSA加密&解密
复制代码
尝试了几次,下面的代码没法添加到代码格式里。所以只能贴在正文里了。

    #region RSA加密&解密
    public class RSAMethod
    {
        ///1024bit
        //        public static string publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfRTdcPIH10gT9f31rQuIInLwe7fl2dtEJ93gTmjE9c2H+kLVENWgECiJVQ5sonQNfwToMKdO0b3Olf4pgBKeLThra
        //                                        z/L3nYJYlbqjHC3jTjUnZc0luumpXGsox62+PuSGBlfb8zJO6hix4GV/vhyQVCpG9aYqgE7zyTRZYX9byQIDAQAB";
        public static string publicKey = @"<RSAKeyValue><Modulus>n0U3XDyB9dIE/X99a0LiCJy8Hu35dnbRCfd4E5oxPXNh/pC1RDVoBAoiVUObKJ0DX8E6DCnTtG9zpX+KYASni04a2s/y952CWJW6oxwt4041J2XNJbrpqVxrKMetvj7khgZX2/MyTuoYseBlf74ckFQqRvWmKoBO88k0WWF/W8k=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
        public static string privateKey = @"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJ9FN1w8gfXSBP1/
                                                    fWtC4gicvB7t+XZ20Qn3eBOaMT1zYf6QtUQ1aAQKIlVDmyidA1/BOgwp07Rvc6V/
                                                    imAEp4tOGtrP8vedgliVuqMcLeNONSdlzSW66alcayjHrb4+5IYGV9vzMk7qGLHg
                                                    ZX++HJBUKkb1piqATvPJNFlhf1vJAgMBAAECgYA736xhG0oL3EkN9yhx8zG/5RP/
                                                    WJzoQOByq7pTPCr4m/Ch30qVerJAmoKvpPumN+h1zdEBk5PHiAJkm96sG/PTndEf
                                                    kZrAJ2hwSBqptcABYk6ED70gRTQ1S53tyQXIOSjRBcugY/21qeswS3nMyq3xDEPK
                                                    XpdyKPeaTyuK86AEkQJBAM1M7p1lfzEKjNw17SDMLnca/8pBcA0EEcyvtaQpRvaL
                                                    n61eQQnnPdpvHamkRBcOvgCAkfwa1uboru0QdXii/gUCQQDGmkP+KJPX9JVCrbRt
                                                    7wKyIemyNM+J6y1ZBZ2bVCf9jacCQaSkIWnIR1S9UM+1CFE30So2CA0CfCDmQy+y
                                                    7A31AkB8cGFB7j+GTkrLP7SX6KtRboAU7E0q1oijdO24r3xf/Imw4Cy0AAIx4KAu
                                                    L29GOp1YWJYkJXCVTfyZnRxXHxSxAkEAvO0zkSv4uI8rDmtAIPQllF8+eRBT/deD
                                                    JBR7ga/k+wctwK/Bd4Fxp9xzeETP0l8/I+IOTagK+Dos8d8oGQUFoQJBAI4Nwpfo
                                                    MFaLJXGY9ok45wXrcqkJgM+SN6i8hQeujXESVHYatAIL/1DgLi+u46EFD69fw0w+c7o0HLlMsYPAzJw=";

        #region 私钥pem to rsa 1024
        public static RSACryptoServiceProvider DecodePemPrivateKey(String pemstr)
        {
            byte[] pkcs8privatekey;
            pkcs8privatekey = Convert.FromBase64String(pemstr);
            if (pkcs8privatekey != null)
            {
                RSACryptoServiceProvider rsa = DecodePrivateKeyInfo(pkcs8privatekey);
                return rsa;
            }
            else
                return null;
        }
        private static RSACryptoServiceProvider DecodePrivateKeyInfo(byte[] pkcs8)
        {

            byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
            byte[] seq = new byte[15];

            MemoryStream mem = new MemoryStream(pkcs8);
            int lenstream = (int)mem.Length;
            BinaryReader binr = new BinaryReader(mem);
            byte bt = 0;
            ushort twobytes = 0;

            try
            {
                twobytes = binr.ReadUInt16();
                if (twobytes == 0x8130)
                    binr.ReadByte();
                else if (twobytes == 0x8230)
                    binr.ReadInt16();
                else
                    return null;

                bt = binr.ReadByte();
                if (bt != 0x02)
                    return null;

                twobytes = binr.ReadUInt16();

                if (twobytes != 0x0001)
                    return null;

                seq = binr.ReadBytes(15);
                if (!CompareBytearrays(seq, SeqOID))
                    return null;

                bt = binr.ReadByte();
                if (bt != 0x04)
                    return null;

                bt = binr.ReadByte();
                if (bt == 0x81)
                    binr.ReadByte();
                else
                    if (bt == 0x82)
                        binr.ReadUInt16();
                byte[] rsaprivkey = binr.ReadBytes((int)(lenstream - mem.Position));
                RSACryptoServiceProvider rsacsp = DecodeRSAPrivateKey(rsaprivkey);
                Console.WriteLine(rsacsp.ToXmlString(true));
                return rsacsp;
            }
            catch (Exception)
            {
                return null;
            }
            finally { binr.Close(); }
        }

        private static bool CompareBytearrays(byte[] a, byte[] b)
        {
            if (a.Length != b.Length)
                return false;
            int i = 0;
            foreach (byte c in a)
            {
                if (c != b)
                    return false;
                i++;
            }
            return true;
        }
        private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
        {
            byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
            MemoryStream mem = new MemoryStream(privkey);
            BinaryReader binr = new BinaryReader(mem);
            byte bt = 0;
            ushort twobytes = 0;
            int elems = 0;
            try
            {
                twobytes = binr.ReadUInt16();
                if (twobytes == 0x8130)
                    binr.ReadByte();
                else if (twobytes == 0x8230)
                    binr.ReadInt16();
                else
                    return null;

                twobytes = binr.ReadUInt16();
                if (twobytes != 0x0102)
                    return null;
                bt = binr.ReadByte();
                if (bt != 0x00)
                    return null;

                elems = GetIntegerSize(binr);
                MODULUS = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                E = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                D = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                P = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                Q = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                DP = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                DQ = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                IQ = binr.ReadBytes(elems);

                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                RSAParameters RSAparams = new RSAParameters();
                RSAparams.Modulus = MODULUS;
                RSAparams.Exponent = E;
                RSAparams.D = D;
                RSAparams.P = P;
                RSAparams.Q = Q;
                RSAparams.DP = DP;
                RSAparams.DQ = DQ;
                RSAparams.InverseQ = IQ;
                RSA.ImportParameters(RSAparams);
                return RSA;
            }
            catch (Exception)
            {
                return null;
            }
            finally { binr.Close(); }
        }
        private static int GetIntegerSize(BinaryReader binr)
        {
            byte bt = 0;
            byte lowbyte = 0x00;
            byte highbyte = 0x00;
            int count = 0;
            bt = binr.ReadByte();
            if (bt != 0x02)
                return 0;
            bt = binr.ReadByte();

            if (bt == 0x81)
                count = binr.ReadByte();
            else
                if (bt == 0x82)
                {
                    highbyte = binr.ReadByte();
                    lowbyte = binr.ReadByte();
                    byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
                    count = BitConverter.ToInt32(modint, 0);
                }
                else
                {
                    count = bt;
                }
            while (binr.ReadByte() == 0x00)
            {
                count -= 1;
            }
            binr.BaseStream.Seek(-1, SeekOrigin.Current);
            return count;

        }
        #endregion


        /// <summary>
        /// RSA的加密函数  string
        /// </summary>
        /// <param name="publicKey">公钥</param>
        /// <param name="plaintext">明文</param>
        /// <returns></returns>
        public string Encrypt(string plaintext)
        {
            return Encrypt(Encoding.UTF8.GetBytes(plaintext));
        }

        /// <summary>
        /// RSA的加密函数  string
        /// </summary>
        /// <param name="publicKey">公钥</param>
        /// <param name="plainbytes">明文字节数组</param>
        /// <returns></returns>
        public string Encrypt(byte[] plainbytes)
        {
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                //rsa.FromXmlString(Encoding.UTF8.GetString(Convert.FromBase64String(publicKey)));
                rsa.FromXmlString(publicKey);
                var bufferSize = (rsa.KeySize / 8 - 11);
                byte[] buffer = new byte[bufferSize];//待加密块

                using (MemoryStream msInput = new MemoryStream(plainbytes))
                {
                    using (MemoryStream msOutput = new MemoryStream())
                    {
                        int readLen;
                        while ((readLen = msInput.Read(buffer, 0, bufferSize)) > 0)
                        {
                            byte[] dataToEnc = new byte[readLen];
                            Array.Copy(buffer, 0, dataToEnc, 0, readLen);
                            byte[] encData = rsa.Encrypt(dataToEnc, false);
                            msOutput.Write(encData, 0, encData.Length);
                        }

                        byte[] result = msOutput.ToArray();
                        rsa.Clear();
                        return Convert.ToBase64String(result);
                    }
                }
            }
        }

        /// <summary>
        /// RSA的解密函数  stirng
        /// </summary>
        /// <param name="privateKey">私钥</param>
        /// <param name="ciphertext">密文字符串</param>
        /// <returns></returns>
        public string Decrypt(string ciphertext)
        {
            return Decrypt(Convert.FromBase64String(ciphertext));
        }

        /// <summary>
        /// RSA的解密函数  byte
        /// </summary>
        /// <param name="privateKey">私钥</param>
        /// <param name="cipherbytes">密文字节数组</param>
        /// <returns></returns>
        public string Decrypt(byte[] cipherbytes)
        {
            using (RSACryptoServiceProvider rsa = DecodePemPrivateKey(privateKey))// new RSACryptoServiceProvider())
            {
                //rsa.FromXmlString(Encoding.UTF8.GetString(Convert.FromBase64String(privateKey)));
                //rsa.FromXmlString(privatekey);
                int keySize = rsa.KeySize / 8;
                byte[] buffer = new byte[keySize];
                using (MemoryStream msInput = new MemoryStream(cipherbytes))
                {
                    using (MemoryStream msOutput = new MemoryStream())
                    {
                        int readLen;

                        while ((readLen = msInput.Read(buffer, 0, keySize)) > 0)
                        {
                            byte[] dataToDec = new byte[readLen];
                            Array.Copy(buffer, 0, dataToDec, 0, readLen);
                            byte[] decData = rsa.Decrypt(dataToDec, false);
                            msOutput.Write(decData, 0, decData.Length);
                        }

                        byte[] result = msOutput.ToArray();
                        rsa.Clear();

                        return Encoding.UTF8.GetString(result);
                    }
                }
            }
        }
    }
    #endregion


 楼主| 发表于 2018-12-28 09:15:39 | 显示全部楼层
本帖最后由 xyx115 于 2018-12-28 09:30 编辑

AU3加密出来的密文是一串数字,但C#加密出来的是一串代码。比如我加密123,加密出来的是这样的:
  1. 52069207266251834503127086198696871286918807063252586384058336631647017447628158474088018576393196351452331111362347081916395874882446991420871941425285035195017992174952004648767522672216397219970258833222060786802329309278462354314392721605467278419858161391564092140348825532340119740012257701744676910132
复制代码

但用C#加密出来的是
  1. Bo83RlfdocH4z66hTFluI+1Cm81TRlznSG3QmaSmHU6G5/LCN1bBAGfv9kMM5eaeSpYo//OoxVZTK3SYGpLn3N+Vof82jQW4aR2W3lX8DWFprAeXJ5JVOilov9vdnPXHnmUPb7Btwes0m6KdnSDE73mmY3nOH4T8ZXjb9awZXtM=
复制代码


AU3加密的时候,提供的是E、D、N。比如kk_lee69的帖子http://www.autoit3.cn/thread-56899-1-1.html,在代码的开头定义了,加解密中也使用了16位编码的转换。
  1. $base16 = "0123456789ABCDEF" ;hex
复制代码
比如的帖子http://www.autoit3.cn/thread-59562-1-1.html,确实很详细,但看不懂这里面的区别。也没有看出使用或者没试用编码转换。

  1. Opt('MustDeclareVars', 1)

  2. Global $iN, $iD, $sEnCrypt, $bEnCrypt, $sDeCrypt, $iStart, $sTime

  3. ;使用公钥加密,只能使用私钥解密文本
  4. ;(以编译形式,它工作得更快)

  5. ;{D,N} 私钥,以前由_RSA_GenerateKeys()函数获取,
  6. ;与公钥一起使用
  7. $iD = 11935633 ;D:秘密指数
  8. $iN = 15861917 ;N:模块(模数)

  9. ;用于解密的字符串
  10. $sEnCrypt = '1991288|12101493|8174576|190045|13592692|6979176|8174576|10777808|8791096|15422074|' & _
  11.                 '8773439|13330816|8791096|911805|15111843|11315347|15412649|8791096|15412649|12101493|' & _
  12.                 '7861534|911805|11315347|8174576|8331591|15412649|670047|13592692|6979176|15412649|' & _
  13.                 '8791096|670047|8791096|13592692|670047|5949229|7861534|190045|6536683|10777808|8791096|' & _
  14.                 '520095|4014646|1604542|1604542|8791096|5949229|15412649|3465002|13592692|8791096|670047|' & _
  15.                 '8791096|15684537|7861534|12030777|6979176|13592692|11315347|10777808|8791096|8773439|5800118|' & _
  16.                 '4275885|10499899|9933837|3733123|4275885|1858732|4275885|5800118|8791096|13330816|9523744|' & _
  17.                 '10499899|11596551|4275885|5800118|5847036|9933837|3827706'

  18. ;加密以前打开的关键文本:
  19. ;描述RSA于1977年8月在“科学美国人”杂志上发表.

  20. ;解密字符串$sDeCrypt中的$sEnCrypt文本:
  21. $iStart = TimerInit()
  22. $sDeCrypt = _RSA_DeCrypt($sEnCrypt, $iD, $iN)
  23. $sTime = StringFormat('%.2f ms', TimerDiff($iStart))
  24. MsgBox(64, $sTime, '加密的字符串文本:' & @LF & $sEnCrypt & @LF & @LF & _
  25.                 '解密文本:' & @LF & $sDeCrypt)
  26. $sDeCrypt = ''



  27. ; #FUNCTION# ====================================================================================================
  28. ; Name...........: _RSA_DeCrypt
  29. ; Description....: 使用闭合{D,N}或者使用RSA算法解密加密文本
  30. ;                  打开{E,N}键.
  31. ; Syntax.........: _RSA_DeCrypt($v_EnCrypt, $i_ED, $i_N)
  32. ; Parameters.....: $v_EnCrypt - 字符串或二进制形式的密文.
  33. ;                  $i_ED - 指数是私人(私人指数)D或公共(公共指数)E,
  34. ;                  取决于文本加密的密钥.
  35. ;                  $i_N - 模块(模数)N.
  36. ;
  37. ; Return values..: Success - 字符串形式的解码字符串.
  38. ;                  Failure - 空字符串和@error标志:
  39. ;                            1 - 没有要解密的文本;
  40. ;                            2 - 没有模块或指数.
  41. ;                            3 - 在解码文本中没有数字.
  42. ; Author.........: madmasles
  43. ; Modified.......:
  44. ; Remarks........: 使用公钥加密的文本只能使用私钥解密,
  45. ;                  反之亦然。 两个密钥必须由_RSA_GenerateKeys函数生成.
  46. ; Related........: __RSA_Calculate
  47. ; Link...........: http://autoit-script.ru/index.php/topic,8343.0.html
  48. ; Example........: 有
  49. ; ===============================================================================================================
  50. Func _RSA_DeCrypt($v_EnCrypt, $i_ED, $i_N)
  51.         Local $a_String, $a_Uniq[1], $i_Count, $s_DeCrypt

  52.         If Not $v_EnCrypt Then Return SetError(1, 0, 0)
  53.         $i_ED = Abs(Int($i_ED))
  54.         $i_N = Abs(Int($i_N))
  55.         If Not $i_ED Or Not $i_N Then Return SetError(2, 0, 0)
  56.         If IsBinary($v_EnCrypt) Then $v_EnCrypt = BinaryToString($v_EnCrypt)
  57.         $a_String = StringRegExp('|000|' & $v_EnCrypt, '\d+', 3)
  58.         $a_String[0] = UBound($a_String) - 1
  59.         If Not $a_String[0] Then Return SetError(3, 0, 0)
  60.         ReDim $a_Uniq[$a_String[0] + 1][2]
  61.         For $i = 1 To $a_String[0]
  62.                 Assign($a_String[$i], Eval($a_String[$i]) + 1)
  63.                 If Eval($a_String[$i]) = 1 Then
  64.                         $i_Count += 1
  65.                         $a_Uniq[$i_Count][0] = $a_String[$i]
  66.                         $a_Uniq[$i_Count][1] = __RSA_Calculate($a_String[$i], $i_ED, $i_N)
  67.                 EndIf
  68.         Next
  69.         For $i = 1 To $a_String[0]
  70.                 For $j = 1 To $i_Count
  71.                         If $a_String[$i] == $a_Uniq[$j][0] Then
  72.                                 $s_DeCrypt &= Chr($a_Uniq[$j][1])
  73.                         EndIf
  74.                 Next
  75.         Next
  76.         Return $s_DeCrypt
  77. EndFunc   ;==>_RSA_DeCrypt



  78. ; #FUNCTION# ====================================================================================================
  79. ; Name...........: __RSA_Calculate
  80. ; Description....: 执行适当的加密计算(解密)。 用于函数_RSA_EnCrypt,_RSA_DeCrypt,__ RSA_ControlKeys。
  81. ; Author.........: Authenticity; http://www.autoitscript.com/forum/topic/95363-rsa-algorithm/page__view__findpost__p__685973
  82. ; Modified.......: madmasles
  83. ; ===============================================================================================================
  84. Func __RSA_Calculate($i_Num, $i_ED, $i_N)
  85.         Local $i_Result = 1

  86.         While $i_ED > 0
  87.                 While Not Mod($i_ED, 2)
  88.                         $i_Num = Mod($i_Num * $i_Num, $i_N)
  89.                         $i_ED /= 2
  90.                 WEnd
  91.                 $i_Result = Mod($i_Num * $i_Result, $i_N)
  92.                 $i_ED -= 1
  93.         WEnd
  94.         Return Int($i_Result)
  95. EndFunc   ;==>__RSA_Calculate



复制代码

C#加密的时候,提供的是私钥,私钥又是由E、N计算组合而成。例如私钥如下
  1. -----BEGIN RSA PRIVATE KEY-----
  2. MIICXQIBAAKBgQCfRTdcPIH10gT9f31rQuIInLwe7fl2dtEJ93gTmjE9c2H+kLVE
  3. NWgECiJVQ5sonQNfwToMKdO0b3Olf4pgBKeLThraz/L3nYJYlbqjHC3jTjUnZc0l
  4. uumpXGsox62+PuSGBlfb8zJO6hix4GV/vhyQVCpG9aYqgE7zyTRZYX9byQIDAQAB
  5. AoGAO9+sYRtKC9xJDfcocfMxv+UT/1ic6EDgcqu6Uzwq+Jvwod9KlXqyQJqCr6T7
  6. pjfodc3RAZOTx4gCZJverBvz053RH5GawCdocEgaqbXAAWJOhA+9IEU0NUud7ckF
  7. yDko0QXLoGP9tanrMEt5zMqt8QxDyl6Xcij3mk8rivOgBJECQQDNTO6dZX8xCozc
  8. Ne0gzC53Gv/KQXANBBHMr7WkKUb2i5+tXkEJ5z3abx2ppEQXDr4AgJH8Gtbm6K7t
  9. EHV4ov4FAkEAxppD/iiT1/SVQq20be8CsiHpsjTPiestWQWdm1Qn/Y2nAkGkpCFp
  10. yEdUvVDPtQhRN9EqNggNAnwg5kMvsuwN9QJAfHBhQe4/hk5Kyz+0l+irUW6AFOxN
  11. KtaIo3TtuK98X/yJsOAstAACMeCgLi9vRjqdWFiWJCVwlU38mZ0cVx8UsQJBALzt
  12. M5Er+LiPKw5rQCD0JZRfPnkQU/3XgyQUe4Gv5PsHLcCvwXeBcafcc3hEz9JfPyPi
  13. Dk2oCvg6LPHfKBkFBaECQQCODcKX6DBWiyVxmPaJOOcF63KpCYDPkjeovIUHro1x
  14. ElR2GrQCC/9Q4C4vruOhBQ+vX8NMPnO6NBy5TLGDwMyc
  15. -----END RSA PRIVATE KEY-----
复制代码
在上面的这段C#的私钥中,我提取出来的E、D、N 以及其他的一些信息,是多行数字。如下:
  1. 公钥(n)
  2. 1118434615188234997140752022447969633236865112888955548889647044
  3. 1990305075187664695743706968317951421906729144097379148372090927
  4. 1436142913114564178481867457362632021524492892634303175288292404
  5. 5233062844805259464020957198604164651230097935720932536523699946
  6. 43487154004307258827356874445534889890144868951350217
  7. 公钥(e)
  8. 65537
  9. 私钥(d)
  10. 4204475886047964603896532886316222569549513372025756116086216065
  11. 4182392562582738774896273643659210702582676339034000652828662308
  12. 6252384599600762571563814032663845633012979302539168462881533747
  13. 6638889263410966169351096412970867668605620339309257907565543548
  14. 5619143510512897386780232632223924485016599868212369
  15. 私钥(p)
  16. 1075246049253473407382111261696749666694448300426383760257426927
  17. 0536320635246929710045770945401864126010928880100258940757746136
  18. 418737740914548702510775813
  19. 私钥(q)
  20. 1040166216806606021691154066770153577402543492706648154517508349
  21. 9445104169204161205344193463225493477699367471117650471089969706
  22. 001061087808468151440248309
  23. d mod (p-1)
  24. 6517398425400152224674151663890883586336003217440174022684289370
  25. 9322184554457640081459054432632505384997503522148204245336330244
  26. 45701481912347722027832497
  27. d mod (q-1)
  28. 9894887257669872868198622020952813621249701925523486358124348164
  29. 9969570521211563877806185402342213615772672783215405186327276401
  30. 25885415236143528592868769
  31. q-1 mod p
  32. 7439958603744371098960975464704294270993416056027789419359189852
  33. 2641802909271996437711960804946403162348218784931517332545316251
  34. 16483765461176980311428252
  35. 复制代码
复制代码

AU3在加密示例中的都是数字,单行数字,加密出来的也是数字。现在我的问题是:
1.C#中解密出来的这种E、D、N的多行数字,在AU3中如何表示,如何使用。
2.AU3如果要解密C#中加密出来的这种密码(听说是utf-8格式),如何用AU3解读,解密。
3.AU3加密出来的数字,如何转换成这种UTF-8的格式,能够被C#的程序正确解密。(使用和AU3相同的E、D、N生成的私钥)。
4.AU3使用E、D、N解密的方法,在论坛中可见可用。但使用C#的私钥、公钥加密解密的方法,尚未见到,不知道有没有强者能给予知道。


回复 支持 1 反对 0

使用道具 举报

发表于 2018-12-24 21:08:07 | 显示全部楼层
你也在研究md5withrsa算法?以前看过的一份C#源码,java语法和C#差不多,

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?加入

x
 楼主| 发表于 2018-12-25 09:11:01 | 显示全部楼层
lpxx 发表于 2018-12-24 21:08
你也在研究md5withrsa算法?以前看过的一份C#源码,java语法和C#差不多,

就是看了你的帖子,启发很大。

但是现在一个工作内容,需要对密码进行解密,研发使用C#开发,我使用的是AU3,他们提供的RSA加解密的公钥、私钥、我没法转换成AU3的。

 楼主| 发表于 2018-12-26 13:41:21 | 显示全部楼层
xyx115 发表于 2018-12-25 09:11
就是看了你的帖子,启发很大。

但是现在一个工作内容,需要对密码进行解密,研发使用C#开发,我使用的 ...

在网上搜索到一个题目:RSA密钥的数据类型转换:由合法的string到PublicKey或PrivateKey来源:https://www.cnblogs.com/KKatherine/p/4128444.html

同样的。这段代码也没能让我弄清楚AU3下面的E、D、N和我提问里的加密字符串之间的关系,以及如何转换。

  1. <blockquote>package pack1;
复制代码
package pack1;

import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;


public class RSAtest{
    public static final String KEY_ALGORITHM="RSA";
    public static final String SIGNATURE_ALGORITHM="MD5withRSA";
    private static final int KEY_SIZE=1024;
    private static final String PUBLIC_KEY="RSAPublicKey";
    private static final String PRIVATE_KEY="RSAPrivateKey";
    public static String str_pubK = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqPvovSfXcwBbW8cKMCgwqNpsYuzF8RPAPFb7LGsnVo44JhM/xxzDyzoYtdfNmtbIuKVi9PzIsyp6rg+09gbuI6UGwBZ5DWBDBMqv5MPdOF5dCQkB2Bbr5yPfURPENypUz+pBFBg41d+BC+rwRiXELwKy7Y9caD/MtJyHydj8OUwIDAQAB";
    public static String str_priK = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKo++i9J9dzAFtbxwowKDCo2mxi7MXxE8A8VvssaydWjjgmEz/HHMPLOhi1182a1si4pWL0/MizKnquD7T2Bu4jpQbAFnkNYEMEyq/kw904Xl0JCQHYFuvnI99RE8Q3KlTP6kEUGDjV34EL6vBGJcQvArLtj1xoP8y0nIfJ2Pw5TAgMBAAECgYAGGB8IllMwxceLhjf6n1l0IWRH7FuHIUieoZ6k0p6rASHSgWiYNRMxfecbtX8zDAoG0QAWNi7rn40ygpR5gS1fWDAKhmnhKgQIT6wW0VmD4hraaeyP78iy8BLhlvblri2nCPIhDH5+l96v7D47ZZi3ZSOzcj89s1eS/k7/N4peEQJBAPEtGGJY+lBoCxQMhGyzuzDmgcS1Un1ZE2pt+XNCVl2b+T8fxWJH3tRRR8wOY5uvtPiK1HM/IjT0T5qwQeH8Yk0CQQC0tcv3d/bDb7bOe9QzUFDQkUSpTdPWAgMX2OVPxjdq3Sls9oA5+fGNYEy0OgyqTjde0b4iRzlD1O0OhLqPSUMfAkEAh5FIvqezdRU2/PsYSR4yoAdCdLdT+h/jGRVefhqQ/6eYUJJkWp15tTFHQX3pIe9/s6IeT/XyHYAjaxmevxAmlQJBAKSdhvQjf9KAjZKDEsa7vyJ/coCXuQUWSCMNHbcR5aGfXgE4e45UtUoIE1eKGcd6AM6LWhx3rR6xdFDpb9je8BkCQB0SpevGfOQkMk5i8xkEt9eeYP0fi8nv6eOUcK96EXbzs4jV2SAoQJ9oJegPtPROHbhIvVUmNQTbuP10Yjg59+8=";
      /**
       * 使用getPublicKey得到公钥,返回类型为PublicKey
       * @param base64 String to PublicKey
       * @throws Exception
       */
      public static PublicKey getPublicKey(String key) throws Exception {
            byte[] keyBytes;
            keyBytes = (new BASE64Decoder()).decodeBuffer(key);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(keySpec);
            return publicKey;
      }
      /**
       * 转换私钥
       * @param base64 String to PrivateKey
       * @throws Exception
       */
      public static PrivateKey getPrivateKey(String key) throws Exception {
            byte[] keyBytes;
            keyBytes = (new BASE64Decoder()).decodeBuffer(key);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            return privateKey;
      }

      //***************************签名和验证*******************************
      public static byte[] sign(byte[] data) throws Exception{
        PrivateKey priK = getPrivateKey(str_priK);
          Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);        
          sig.initSign(priK);
          sig.update(data);
          return sig.sign();
      }

      public static boolean verify(byte[] data,byte[] sign) throws Exception{
          PublicKey pubK = getPublicKey(str_pubK);
          Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);
          sig.initVerify(pubK);
          sig.update(data);
          return sig.verify(sign);
      }

      //************************加密解密**************************
      public static byte[] encrypt(byte[] bt_plaintext)throws Exception{
          PublicKey publicKey = getPublicKey(str_pubK);
          Cipher cipher = Cipher.getInstance("RSA");
          cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] bt_encrypted = cipher.doFinal(bt_plaintext);
        return bt_encrypted;
      }

      public static byte[] decrypt(byte[] bt_encrypted)throws Exception{
        PrivateKey privateKey = getPrivateKey(str_priK);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] bt_original = cipher.doFinal(bt_encrypted);
        return bt_original;
      }
      //********************main函数:加密解密和签名验证*********************
      public static void main(String[] args) throws Exception {
            String str_plaintext = "这是一段用来测试密钥转换的明文";
            System.err.println("明文:"+str_plaintext);
            byte[] bt_cipher = encrypt(str_plaintext.getBytes());
            System.out.println("加密后:"+Base64.encodeBase64String(bt_cipher));

            byte[] bt_original = decrypt(bt_cipher);
            String str_original = new String(bt_original);
            System.out.println("解密结果:"+str_original);

            String str="被签名的内容";
            System.err.println("\n原文:"+str);
            byte[] signature=sign(str.getBytes());
            System.out.println("产生签名:"+Base64.encodeBase64String(signature));
            boolean status=verify(str.getBytes(), signature);
            System.out.println("验证情况:"+status);
      }

}


发表于 2018-12-26 14:48:33 | 显示全部楼层
本帖最后由 chzj589 于 2018-12-26 19:23 编辑
xyx115 发表于 2018-12-26 13:41
在网上搜索到一个题目:RSA密钥的数据类型转换:由合法的string到PublicKey或PrivateKey来源:https://ww ...

我不懂,移步看看kk_lee69的帖子
http://www.autoit3.cn/thread-56899-1-1.html



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?加入

x
 楼主| 发表于 2018-12-27 18:04:18 | 显示全部楼层
本帖最后由 xyx115 于 2018-12-27 18:06 编辑
  1. 公钥(n)
  2. 1118434615188234997140752022447969633236865112888955548889647044
  3. 1990305075187664695743706968317951421906729144097379148372090927
  4. 1436142913114564178481867457362632021524492892634303175288292404
  5. 5233062844805259464020957198604164651230097935720932536523699946
  6. 43487154004307258827356874445534889890144868951350217
  7. 公钥(e)
  8. 65537
  9. 私钥(d)
  10. 4204475886047964603896532886316222569549513372025756116086216065
  11. 4182392562582738774896273643659210702582676339034000652828662308
  12. 6252384599600762571563814032663845633012979302539168462881533747
  13. 6638889263410966169351096412970867668605620339309257907565543548
  14. 5619143510512897386780232632223924485016599868212369
  15. 私钥(p)
  16. 1075246049253473407382111261696749666694448300426383760257426927
  17. 0536320635246929710045770945401864126010928880100258940757746136
  18. 418737740914548702510775813
  19. 私钥(q)
  20. 1040166216806606021691154066770153577402543492706648154517508349
  21. 9445104169204161205344193463225493477699367471117650471089969706
  22. 001061087808468151440248309
  23. d mod (p-1)
  24. 6517398425400152224674151663890883586336003217440174022684289370
  25. 9322184554457640081459054432632505384997503522148204245336330244
  26. 45701481912347722027832497
  27. d mod (q-1)
  28. 9894887257669872868198622020952813621249701925523486358124348164
  29. 9969570521211563877806185402342213615772672783215405186327276401
  30. 25885415236143528592868769
  31. q-1 mod p
  32. 7439958603744371098960975464704294270993416056027789419359189852
  33. 2641802909271996437711960804946403162348218784931517332545316251
  34. 16483765461176980311428252
复制代码
那天的私钥我已经在网上找工具解密出来E、D、N,但是示范中的数字都是单行的,我解密出来的是多行的,还是不会用。不知道怎么才能用这些解密出来的数值。

有没有人知道该怎么办。

您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|小黑屋|手机版|AUTOIT CN ( 鲁ICP备15028933号-3 )谷歌 百度

GMT+8, 2019-1-19 17:30 , Processed in 0.117815 second(s), 16 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表