Pedro
Pedro

Reputation: 5

Base64 encoding of a SHA256 string

I am currently doing a program in C #. When I tried to pass my string from sha256 to base64, I realized that it was not being encoded correctly.

For instance, given the sha256

cd69ef0284bba33bc0b320e6479c2da2d411a5e46af060d8639f0e0bfc24f26d

My code produces

Y2Q0Q2OUVGMDI4NEJCQTMzQkMwQjMyMEU2NDc5QzJEQTJENDExQTVFNDZBRjA2MEQ4NjM5RjBFMEJGQzI0RjI2RA==

What I'm expecting to get is

zWnvAoS7ozvAsyDmR5wtotQRpeRq8GDYY58OC/wk8m0

Why are encoded strings so different and what am I missing?

This is the code I am using

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

Upvotes: 0

Views: 12032

Answers (2)

Aravindh Kumar
Aravindh Kumar

Reputation: 56

We can now use 'Base64UrlTextEncoder' from 'Microsoft.AspNetCore.WebUtilities' in .Net core applications.

What you are looking for is URL safe Base64 string version which is predominantly seen in OAuth(PIKCE) flows.

using var alg = SHA256.Create();
using var stream = new MemoryStream(Encoding.UTF8.GetBytes("R15iKJ_Kx4r1gX0TMwzCnpkq3Zqcz-h-r00BhshyQ6o"));
var hashBytes = alg.ComputeHashAsync(stream).Result;
Console.WriteLine($"URL safe Base64: {Base64UrlTextEncoder.Encode(hashBytes)}");

Some sample outputs:

Hex string: 051627b9015ffdd5672903e226089fda574c825acc5d46e83b02310ef329c04

Normal Base64: UFFie5AV/91WcpA+ImCJ/aV0yCWsxdRug7AjEO8ynAQ=

URL safe Base64: UFFie5AV_91WcpA-ImCJ_aV0yCWsxdRug7AjEO8ynAQ

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1502066

The output of SHA-256 is a binary value, typically expressed as a byte array. You've converted that into a hex string, then base64-encoded that hex string.

Instead, you should be base64-encoding the original binary data, without converting it to hex first.

If you have to go via the hex first, you should parse that back to the original bytes, then base64 encode the result:

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

... but it would be better just not to convert the hash into hex to start with.

Upvotes: 7

Related Questions