【问题标题】:Base64 encoding of a SHA256 stringSHA256 字符串的 Base64 编码
【发布时间】:2018-12-28 22:28:26
【问题描述】:

我目前正在用 C# 编写一个程序。当我尝试将字符串从 sha256 传递到 base64 时,我意识到它没有被正确编码。

例如,给定 sha256

cd69ef0284bba33bc0b320e6479c2da2d411a5e46af060d8639f0e0bfc24f26d

我的代码产生

Y2Q0Q2OUVGMDI4NEJCQTMzQkMwQjMyMEU2NDc5QzJEQTJENDExQTVFNDZBRjA2MEQ4NjM5RjBFMEJGQzI0RjI2RA==

我期望得到的是

zWnvAoS7ozvAsyDmR5wtotQRpeRq8GDYY58OC/wk8m0

为什么编码的字符串如此不同,我错过了什么?

这是我正在使用的代码

string t1 ="cd69ef0284bba33bc0b320e6479c2da2d411a5e46af060d8639f0e0bfc24f26d";
var t2= System.Text.Encoding.GetEncoding(1252).GetBytes(t1);                                
string t3= System.Convert.ToBase64String(t2);

【问题讨论】:

  • zWnvAoS7ozvAsyDmR5wtotQRpeRq8GDYY58OC/wk8m0 的期望值从何而来?如果您向我们展示您的源代码,将会有所帮助。
  • @ Griswald_911我从我的代码得到这个 'Y2Q0Q2OUVGMDI4NEJCQTMzQkMwQjMyMEU2NDc5QzJEQTJENDExQTVFNDZBRjA2MEQ4NjM5RjBFMEJGQzI0RjI2RA ==' 我希望得到这个 'zWnvAoS7ozvAsyDmR5wtotQRpeRq8GDYY58OC / wk8m0' SPAN>
  • @Pedro 你是如何得到zWnvAoS7ozvAsyDmR5wtotQRpeRq8GDYY58OC/wk8m0 的值的?你首先要计算什么?
  • 他的预期结果可以反转:BitConverter.ToString(Convert.FromBase64String("zWnvAoS7ozvAsyDmR5wtotQRpeRq8GDYY58OC/wk8m0" + "=")).Replace("-", String.Empty).ToLowerInvariant(),你会得到他输入的 SHA256 值。因此,@daisy-shipton 的猜测可能是正确的,他是如何得到预期结果的。
  • @Pedro:请参阅下面 Daisy 的回答。正如她解释的那样,您真的只想从 SHA-256 哈希中获取原始二进制文件,并将其直接传递给接受 byte[] 的 System.Convert.ToBase64String 方法。当您到达t1 的字符串值时,您已经走得太远了。换句话说,最好将散列编码为 base64,而不是该散列的字符串或十六进制表示。

标签: c# base64 sha256


【解决方案1】:

SHA-256 的输出是二进制值,通常表示为字节数组。您已将其转换为十六进制字符串,然后对该十六进制字符串进行 base64 编码。

相反,您应该对原始二进制数据进行 base64 编码,而不是先将其转换为十六进制。

如果你必须先通过十六进制,你应该把它解析回原始字节,然后base64编码结果:

using System;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        string text = "cd69ef0284bba33bc0b320e6479c2da2d411a5e46af060d8639f0e0bfc24f26d";
        byte[] data = ParseHex(text);
        Console.WriteLine(Convert.ToBase64String(data));
    }

    // Taken from https://stackoverflow.com/questions/795027/code-golf-hex-to-raw-binary-conversion/795036#795036
    static byte[] ParseHex(string text)
    {
        Func<char, int> parseNybble = c => (c >= '0' && c <= '9') ? c-'0' : char.ToLower(c)-'a'+10;
        return Enumerable.Range(0, text.Length/2)
            .Select(x => (byte) ((parseNybble(text[x*2]) << 4) | parseNybble(text[x*2+1])))
            .ToArray();
    }
}

...但最好不要将散列转换为十六进制开始。

【讨论】:

  • 我得到这个 'zWnvAoS7ozvAsyDmR5wtotQRpeRq8GDYY58OC/wk8m0=' 但我想要这个 'zWnvAoS7ozvAsyDmR5wtotQRpeRq8GDYY58OC/wk8m0' 你知道我为什么得到 '=' 吗?
  • @Pedro:这是 base64 的填充。就常规base64而言,这是正确的。一些 base64 方案会对其进行修剪并依赖于文本的长度 - 如果您的情况属于这种情况,您可以使用 TrimEnd 删除任何尾随的 = 符号。
猜你喜欢
  • 2018-06-12
  • 2021-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 2014-11-29
相关资源
最近更新 更多