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

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

提问人:M.Saeed 提问时间:6/8/2022 最后编辑:TopacoM.Saeed 更新时间:6/9/2022 访问量:129

问:

我有一个代码将公钥,然后将其添加到QR TLV代码中,但是当我将其添加到QR代码中时,格式与PHP不同,并且与我需要的格式不同!decodebase64

C# 中的 Decoded64 公钥:

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

我需要的是这样:

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

我的 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();
        }
    }
}

我想要的QR输出不一样:

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

正确的预期二维码,如 PHP 中的:

AQxCb2JzIFJlY29yZHMCDzMxMDEyMjM5MzUwMDAwMwMTMjAyMi0wNC0yNSAxNTozMDowMAQIMTAwMDAuMDAFBjE1MC4wMAZYMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYYMMoOaFYAhMO/steotfZyavr6p11SSlwsK9azmsLY7b1b+FLhqMArhB2dqHKboxqKNfvkKDePhpqjui5hcn0Q==

C# 代码出了什么问题,我该如何解决这个问题?我以为是来自 UTF8,但事实并非如此!

C# QR 代码 公钥 TLV

评论


答:

2赞 Topaco 6/8/2022 #1

MFY...cn0Q==是 Base64 编码后 X.509/SPKI 格式的 DER 编码的公共 EC 密钥。这在 的 UTF8 编码期间已损坏,这显示在结果0xEFBFBD的替换字符中。
此外,应避免使用默认编码,而应具体指定编码。
Base64Decode()Encoding.Default

可能的解决方法是:

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

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("-", "");
}

这里将编码移到了外面,因此该方法可以独立于输入编码用于所有标记。GetHexString()

此修复程序给出了预期的结果。