RC4加密不匹配什么样的期望 [英] RC4 encryption not matching what's expected

查看:146
本文介绍了RC4加密不匹配什么样的期望的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用银行的Web服务,通​​过信用卡支付的一些问题。他们需要在出站数据,他们预计将在十六进制格式的RC4加密。

下面是测试网站,他们给我的使用方法: HTTP:// WWW .fyneworks.com /加密/ RC4加密/的index.asp

当我把样卡,并通过在由上面的表格所产生的价值,它们是正确的,并且该卡被接受。当我用我下面的弗兰肯code(从片段,我发现在互联网上拼凑起来),十六进制值仅仅是不正确的,该卡每次都拒绝。在某些情况下,encName,它是完全关闭。在encCCNum和encCVVTest的情况下,它是关于半右。在encExpyMonth和encExpyYear,其完全正确。

的情况下,

我敢肯定,问题是我的算法地方,或者甚至是十六进制的转换,但我真的没有太多经验的加密程序,所以我甚至不知道从哪里开始调试。是否有人可以帮助我吗?这是在C#.NET Web应用程序,顺便说一句。

  rc4encrypt RC4 =新rc4encrypt();
 rc4.Password =B83E13EC;
 rc4.PlainText = sNameTest;
 encName = rc4.EnDeCrypt();
 rc4.Password =B83E13EC;
 rc4.PlainText = sCCNumTest;
 encCCNum = rc4.EnDeCrypt();
 rc4.Password =B83E13EC;
 rc4.PlainText = sExpyMonthTest;
 encExpyMonth = rc4.EnDeCrypt();
 rc4.Password =B83E13EC;
 rc4.PlainText = sExpyYearTest;
 encExpyYear = rc4.EnDeCrypt();
 rc4.Password =B83E13EC;
 rc4.PlainText = sCVVTest;
 encCVVTest = rc4.EnDeCrypt();

   公共类rc4encrypt
    {
        保护INT [] S盒=新INT [256];
        保护INT []键=新INT [256];

        受保护的明文字符串,密码;

        公共字符串纯文本
        {
            集合{明文=价值; }
            {返回明文; }
        }

        公共字符串密码
        {
            集合{密码=价值; }
            {返回密码; }
        }

        私人无效RC4Initialize(字符串strPwd)
        {
            //获取密码的长度
            //相反莱恩(),我们需要使用length属性
            //串的
            INT intLength = strPwd.Length;

            //设置我们的for循环。在C#中,我们需要改变我们的语法。

            //第一个参数是初始化。在这里我们声明
            //为整数,并将其设置为等于零。

            //第二个参数是用来测试前pression
            //对于循环终止。由于我们的阵列具有256
            //元素始终是零基础,我们需要循环,只要
            //作为小于或等于255。

            //第三个参数是用来递增迭代器
            //一个接一个通过每次循环的价值。注意
            //我们可以使用,而不是A = A + 1 ++增量符号
            对于(INT一= 0; A< = 255; A ++)
            {
                //因为我们没有MID()在C#中,我们使用C#
                // MID(),String.Substring当量,获得
                //从strPwd单个字符。我们声明字符
                //变量,CTMP,持有该值。

                //有两件事情要注意。首先,mod关键字我们
                //在VB需要用于替换为%
                //运算符C#使用。接着,由于返回的类型
                // String.Substring是一个字符串,我们需要将其转换为
                //使用String.ToCharArray(),并指定一个字符
                //我们想要的阵列中的第一个值,[0]。

                焦炭CTMP =(strPwd.Substring((A%intLength)
                    1).ToCharArray()[0]);

                //现在,我们有我们的特点和需要得到的ASCII
                // code吧。 C#不具有VB的升序(),但是这
                //并不意味着我们不能使用它。在一开始,我们
                // code,我们进口的Microsoft.VisualBasic命名空间。
                //这使得我们可以使用许多的原VB功能
                //在C#

                //请注意,我们需要使用[],而不是()为我们
                //数组成员。
                键[A] = Microsoft.VisualBasic.Strings.Asc(CTMP);
                S盒[A] = A;
            }

            //声明一个整数x和它初始化为0。
            INT X = 0;

            //再次,创建一个for循环像上面的。请注意,我们
            //需要使用不同的变量,因为我们已把
            //声明的上方。
            为(中间体B = 0; b将= 255; b + +)
            {
                X =(X + S盒[B] +键[B])%256;
                INT tempSwap = S盒[B]。
                S盒[B] = S盒[X]
                S盒[X] = tempSwap;
            }
        }

        公共字符串EnDeCrypt()
        {
            INT I = 0;
            INT J = 0;
            字符串密码=;

            //调用我们的方法来初始化这里使用的阵列。
            RC4Initialize(密码);

            //设置一个for循环。同样,我们使用length属性
            //我们的字符串,而不是莱恩(的)功能

            对于(INT A = 1; A< = plaintext.Length; A ++)
            {
                //初始化我们将在这个循环使用一个整数变量
                INT ITMP = 0;


                //像RC4Initialize方法,我们需要使用%
                //到位的MOD
                I =(1 + 1)%256;
                J =(J + S盒[I])%256;
                ITMP = S盒[I]
                S盒[i] = S盒[J]。
                S盒[J] = ITMP;

                INT K = S盒[(S盒[I] + S盒[J])256%]。

                //同样,由于String.Substring的返回类型是
                //串,我们需要利用将其转换为一个字符
                // String.ToCharArray(),并指定了我们需要的
                //第一值,[0]。

                炭CTMP = plaintext.Substring(一 -  1,1).ToCharArray()
                    [0];

                //使用升序()从Microsoft.VisualBasic命名空间
                ITMP = Microsoft.VisualBasic.Strings.Asc(CTMP);

                //这里我们需要使用C#使用异或^运算符
                INT cipherby = ITMP ^ K表;

                //使用CHR()从Microsoft.VisualBasic命名空间
                密码+ = Microsoft.VisualBasic.Strings.Chr(cipherby);
            }

            //返回密码的值作为返回值我们
            // 方法

            //转换为十六进制 - 国阵加
            字符串finalcipher =的String.Empty;
            的char []值= cipher.ToCharArray();
            的foreach(中值字符字母)
            {
                //获取字符的积分值。
                int值= Convert.ToInt32(函);
                //十进制值转换为字符串形式的十六进制值。
                finalcipher + =的String.Format({0:X},值);

            }

            返回finalcipher;
        }

    }
 

解决方案

别角色你自己的密码code。它通常是错误的。 充气城堡有一个C#实现支持RC4。为什么不使用呢?

I'm having some problems using a bank's web service to pass in credit card payments. They require RC4 encryption on the outbound data, which they expect to be in a hexadecimal format.

Here is the testing website they gave me to use: http://www.fyneworks.com/encryption/rc4-encryption/index.asp

When I take a sample card, and pass in the values generated by the form above, they are correct, and the card is accepted. When I use my frankencode below (cobbled together from snippets I found on the internet), the hexadecimal values are just incorrect, and the card is declined every time. In some cases, encName, it is TOTALLY OFF. In the case of encCCNum and encCVVTest, it is about half-right. In the case of encExpyMonth and encExpyYear, its COMPLETELY RIGHT.

I'm sure the issue is in my algorithm somewhere, or maybe even the hexadecimal conversion, but I'm really not too experienced in cryptography programming, so I don't even know where to begin debugging. Can someone please help me? This is a web application in C#.net, btw.

 rc4encrypt rc4 = new rc4encrypt();
 rc4.Password = "B83E13EC";
 rc4.PlainText = sNameTest;
 encName = rc4.EnDeCrypt();
 rc4.Password = "B83E13EC";
 rc4.PlainText = sCCNumTest;
 encCCNum = rc4.EnDeCrypt();
 rc4.Password = "B83E13EC";
 rc4.PlainText = sExpyMonthTest;
 encExpyMonth = rc4.EnDeCrypt();
 rc4.Password = "B83E13EC";
 rc4.PlainText = sExpyYearTest;
 encExpyYear = rc4.EnDeCrypt();
 rc4.Password = "B83E13EC";
 rc4.PlainText = sCVVTest;
 encCVVTest = rc4.EnDeCrypt();

   public class rc4encrypt
    {
        protected int[] sbox = new int[256];
        protected int[] key = new int[256];

        protected string plaintext, password;

        public string PlainText
        {
            set { plaintext = value; }
            get { return plaintext; }
        }

        public string Password
        {
            set { password = value; }
            get { return password; }
        }

        private void RC4Initialize(string strPwd)
        {
            // Get the length of the password
            // Instead of Len(), we need to use the Length property
            // of the string
            int intLength = strPwd.Length;

            // Set up our for loop.  In C#, we need to change our syntax.

            // The first argument is the initializer.  Here we declare a
            // as an integer and set it equal to zero.

            // The second argument is expression that is used to test
            // for the loop termination.  Since our arrays have 256
            // elements and are always zero based, we need to loop as long
            // as a is less than or equal to 255.

            // The third argument is an iterator used to increment the
            // value of a by one each time through the loop.  Note that
            // we can use the ++ increment notation instead of a = a + 1
            for (int a = 0; a <= 255; a++)
            {
                // Since we don't have Mid()  in C#, we use the C#
                // equivalent of Mid(), String.Substring, to get a
                // single character from strPwd.  We declare a character
                // variable, ctmp, to hold this value.

                // A couple things to note.  First, the Mod keyword we
                // used in VB need to be replaced with the %
                // operator C# uses.  Next, since the return type of
                // String.Substring is a string, we need to convert it to
                // a char using String.ToCharArray() and specifying that
                // we want the first value in the array, [0].

                char ctmp = (strPwd.Substring((a % intLength),
                    1).ToCharArray()[0]);

                // We now have our character and need to get the ASCII
                // code for it.  C# doesn't have the  VB Asc(), but that
                // doesn't mean we can't use it.  In the beginning of our
                // code, we imported the Microsoft.VisualBasic namespace.
                // This allows us to use many of the native VB functions
                // in C#

                // Note that we need to use [] instead of () for our
                // array members.
                key[a] = Microsoft.VisualBasic.Strings.Asc(ctmp);
                sbox[a] = a;
            }

            // Declare an integer x and initialize it to zero.
            int x = 0;

            // Again, create a for loop like the one above.  Note that we
            // need to use a different variable since we've already
            // declared a above.
            for (int b = 0; b <= 255; b++)
            {
                x = (x + sbox[b] + key[b]) % 256;
                int tempSwap = sbox[b];
                sbox[b] = sbox[x];
                sbox[x] = tempSwap;
            }
        }

        public string EnDeCrypt()
        {
            int i = 0;
            int j = 0;
            string cipher = "";

            // Call our method to initialize the arrays used here.
            RC4Initialize(password);

            // Set up a for loop.  Again, we use the Length property
            // of our String instead of the Len() function

            for (int a = 1; a <= plaintext.Length; a++)
            {
                // Initialize an integer variable we will use in this loop
                int itmp = 0;


                // Like the RC4Initialize method, we need to use the %
                // in place of Mod
                i = (i + 1) % 256;
                j = (j + sbox[i]) % 256;
                itmp = sbox[i];
                sbox[i] = sbox[j];
                sbox[j] = itmp;

                int k = sbox[(sbox[i] + sbox[j]) % 256];

                // Again, since the return type of String.Substring is a
                // string, we need to convert it to a char using
                // String.ToCharArray() and specifying that we want the
                // first value, [0].

                char ctmp = plaintext.Substring(a - 1, 1).ToCharArray()
                    [0];

                // Use Asc() from the Microsoft.VisualBasic namespace
                itmp = Microsoft.VisualBasic.Strings.Asc(ctmp);

                // Here we need to use ^ operator that C# uses for Xor
                int cipherby = itmp ^ k;

                // Use Chr() from the Microsoft.VisualBasic namespace                
                cipher += Microsoft.VisualBasic.Strings.Chr(cipherby);
            }

            // Return the value of cipher as the return value of our
            // method

            //Convert to hexadecimal - added by BN
            string finalcipher = string.Empty;
            char[] values = cipher.ToCharArray();
            foreach (char letter in values)
            {
                // Get the integral value of the character. 
                int value = Convert.ToInt32(letter);
                // Convert the decimal value to a hexadecimal value in string form. 
                finalcipher += String.Format("{0:X}", value);

            }

            return finalcipher;
        }

    }

解决方案

Don't role your own crypto code. It usually is wrong. Bouncy castle has a C# implementation that supports RC4. Why not use that ?

这篇关于RC4加密不匹配什么样的期望的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆