RC4加密与期望的不匹配

本文关键字:不匹配 期望 加密 RC4 | 更新日期: 2023-09-27 18:05:36

我在使用银行的web服务来传递信用卡支付时遇到了一些问题。他们需要对出站数据进行RC4加密,他们希望这些数据是十六进制格式的。

这是他们给我使用的测试网站:http://www.fyneworks.com/encryption/rc4-encryption/index.asp

当我取一张样本卡,并将上面表格生成的值传入时,它们是正确的,并且该卡被接受。当我使用下面的弗兰肯代码时(根据我在互联网上找到的片段拼凑而成),十六进制值是不正确的,并且每次卡都被拒绝。在某些情况下,encName是完全关闭的。对于encCCNum和encCVVTest,它只对了一半。对于encExpyMonth和encExpyYear,这是完全正确的。

我确信问题是在我的算法的某个地方,或者甚至十六进制转换,但我真的不太有经验的加密编程,所以我甚至不知道从哪里开始调试。有人能帮帮我吗?这是一个c# .net的web应用程序,顺便说一下。

 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;
        }
    }

RC4加密与期望的不匹配

不要使用自己的加密代码。它通常是错误的。Bouncy castle有一个支持RC4的c#实现。为什么不用呢?