简体   繁体   English

使用 C# 的 TLV QR 标签内的公钥格式不正确

[英]Public key format is not correct inside TLV QR tag using C#

I have a code will decodebase64 the public key and then add it in QR TLV code, but when I add it in QR code the format is different than in PHP, and not same as I need it!我有一个代码将decodebase64公钥然后将其添加到 QR TLV 代码中,但是当我将其添加到 QR 代码中时,格式与 PHP 中的格式不同,并且与我需要的不同!

the Decoded64 Public key in C#: C# 中的 Decoded64 公钥:

0V0*�H�=+�
Ba���L;�-z�_g&���u�$��½k9�-��տ�.��A�ڇ)�1��_�B�x�i�;��'�

the what I need it like this:我需要的是这样的:

X0V0*H=+�
B�a`L;-z_g&u$½k9-տ.Aڇ)1_Bxi;'

my C# code:我的 C# 代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace tlvgenerator
{
    class Program
    {
        static void Main(string[] args)
        {
            static string Base64Decode(string base64EncodedData)
            {
                var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
                return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
            }
            string base64 = "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYYMMoOaFYAhMO/steotfZyavr6p11SSl wsK9azmsLY7b1b+FLhqMArhB2dqHKboxqKNfvkKDePhpqjui5hcn0Q==";
            Console.WriteLine("Encoded String = " + base64);
            var original = Base64Decode(base64);

            byte[] bytes = Encoding.Default.GetBytes(original);
            original = Encoding.UTF8.GetString(bytes);

            Console.WriteLine("Decoded String = " + original);

            string SallerName = gethexstring(1, "Bobs Records"); //Tag1
            string VATReg = gethexstring(2, "310122393500003"); //Tag2
            string DateTimeStr = gethexstring(3, "2022-04-25 15:30:00"); //Tage3
            string TotalAmt = gethexstring(4, "10000.00"); //Tag4
            string VatAmt = gethexstring(5, "150.00"); //Tag5
            string PK = gethexstring(6, original); //Tag6


            string decString = SallerName + VATReg + DateTimeStr + TotalAmt + VatAmt + PK;
            Console.WriteLine(decString);
            Console.WriteLine(HexToBase64(decString));
            Console.Read();


        }
        static string gethexstring(Int32 TagNo, string TagValue)
        {
            string StrTagNo = String.Format("0{0:X}", TagNo);
            String TagNoVal = StrTagNo.Substring(StrTagNo.Length - 2, 2);

            string StrTagValue_Length = String.Format("0{0:X}", TagValue.Length);
            String TagValue_LengthVal = StrTagValue_Length.Substring(StrTagValue_Length.Length - 2, 2);

            string decString = TagValue;
            byte[] bytes = Encoding.Default.GetBytes(decString);
            string hexString = BitConverter.ToString(bytes);
            hexString = TagNoVal + TagValue_LengthVal + hexString.Replace("-", "");

            return hexString;
        }

        static string gethexDec(Int32 TagValue)
        {
            string hxint = String.Format("0{0:X}", TagValue);
            return hxint.Substring(hxint.Length - 2, 2);

        }
        public static string HexToBase64(string strInput)
        {
            try
            {
                var bytes = new byte[strInput.Length / 2];
                for (var i = 0; i < bytes.Length; i++)
                {
                    bytes[i] = Convert.ToByte(strInput.Substring(i * 2, 2), 16);
                }
                return Convert.ToBase64String(bytes);
            }
            catch (Exception)
            {
                return "-1";
            }
        }

        private string StringToHex(string hexstring)
        {
            StringBuilder sb = new StringBuilder();
            foreach (char t in hexstring)
            {
                //Note: X for upper, x for lower case letters
                sb.Append(Convert.ToInt32(t).ToString("x"));
            }
            return sb.ToString();
        }
    }
}

the QR output which is not same I want it: QR输出不一样我想要它:

AQxCb2JzIFJlY29yZHMCDzMxMDEyMjM5MzUwMDAwMwMTMjAyMi0wNC0yNSAxNTozMDowMAQIMTAwMDAuMDAFBjE1MC4wMAZUMFYwEAYHKu+/vUjvv709AgEGBSvvv70EAAoDQgAEYe+/vQzvv73vv71gCEw777+9LXrvv71fZybvv73vv73vv71177+9JO+/ve+/vcK9aznvv70t77+977+91b/vv70uGu+/vQLvv71B77+92ocp77+9Me+/ve+/vV/vv71C77+9eO+/vWnvv70777+977+9Fyfvv70=

the correct expected QR code like in PHP:正确的预期二维码,如 PHP:

AQxCb2JzIFJlY29yZHMCDzMxMDEyMjM5MzUwMDAwMwMTMjAyMi0wNC0yNSAxNTozMDowMAQIMTAwMDAuMDAFBjE1MC4wMAZYMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYYMMoOaFYAhMO/steotfZyavr6p11SSlwsK9azmsLY7b1b+FLhqMArhB2dqHKboxqKNfvkKDePhpqjui5hcn0Q==

What is the wrong in C# code and how can I solve the issue? C# 代码有什么问题,我该如何解决这个问题? I thought was from UTF8 but it's not!我以为来自 UTF8,但不是!

MFY...cn0Q== is a DER encoded public EC key in X.509/SPKI format after Base64 encoding. MFY...cn0Q==是经过 Base64 编码后的 X.509/SPKI 格式的 DER 编码公共 EC 密钥。 This is corrupted during UTF8 encoding in Base64Decode() , which is shown in the replacement characters 0xEFBFBD of the result.这在Base64Decode()中的 UTF8 编码期间被破坏,这显示在结果的替换字符 0xEFBFBD 中。
Also the use of the default encoding in Encoding.Default should be avoided, instead the encoding should be specified concretely.此外,应避免在Encoding.Default中使用默认编码,而是应具体指定编码。

A possible fix is:一个可能的解决方法是:

string base64 = "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYYMMoOaFYAhMO/steotfZyavr6p11SSlwsK9azmsLY7b1b+FLhqMArhB2dqHKboxqKNfvkKDePhpqjui5hcn0Q==";

string sallerName = GetHexString(1, Encoding.UTF8.GetBytes("Bobs Records"));            //Tag1
string vatReg = GetHexString(2, Encoding.UTF8.GetBytes("310122393500003"));             //Tag2
string dateTimeStr = GetHexString(3, Encoding.UTF8.GetBytes("2022-04-25 15:30:00"));    //Tag3
string totalAmt = GetHexString(4, Encoding.UTF8.GetBytes("10000.00"));                  //Tag4
string vatAmt = GetHexString(5, Encoding.UTF8.GetBytes("150.00"));                      //Tag5
string pk = GetHexString(6, Convert.FromBase64String(base64));                          //Tag6

string decString = sallerName + vatReg + dateTimeStr + totalAmt + vatAmt + pk;

Console.WriteLine(HexToBase64(decString));

with

static string GetHexString(int tagNo, byte[] tagValue)
{
    string strTagNo = string.Format("0{0:X}", tagNo);
    string tagNoVal = strTagNo.Substring(strTagNo.Length - 2, 2);

    string strTagValueLength = string.Format("0{0:X}", tagValue.Length);
    string tagValueLengthVal = strTagValueLength.Substring(strTagValueLength.Length - 2, 2);

    return tagNoVal + tagValueLengthVal + BitConverter.ToString(tagValue).Replace("-", "");
}

Here in GetHexString() the encoding was moved outside, so that the method can be used for all tags independently of the input encoding.GetHexString()中,编码被移到外面,因此该方法可以独立于输入编码用于所有标签。

This fix gives the expected result.此修复程序给出了预期的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM