本文介绍了Base64解码失败,并显示为“目标多字节代码页中不存在Unicode字符的映射".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建Azure存储表所需的签名字符串,如下所述:

I am trying to create the signature string needed for Azure Storage Tables as described here:

https://docs.microsoft.com/zh-cn/rest/api/storageservices/authorize-with-shared-key#encoding-the-signature

访问密钥为"p1qPD2lBiMlDtl/Vb/T/Xt5ysd/ZXNg5AGrwJvtrUbyqiAQxGabWkR9NmKWb8Jhd6ZIyBd9HA3kCRHr6eveKaA =="

失败的代码是:

property AccessKey: string read FAccessKey write SetAccessKey;

function TAzureStorageAPI.GetAuthHeader(StringToSign: UTF8String): UTF8String;
var
  AccessKey64: string;
begin
  AccessKey64 := URLEncoding.Base64.Decode(AccessKey);
  Result := URLEncoding.Base64.Encode(CalculateHMACSHA256(StringtoSign,AccessKey64));
end;

我该怎么做才能使它正常工作?

What can I do to get this working?

我已检查 AccessKey 是否在 https://www.base64decode.org/上解码并转换为奇怪的数据,但这是我应该做的....:-/

I have checked that AccessKey decodes on https://www.base64decode.org/ and it converts to strange data, but it is what I am supposed to do.... :-/

推荐答案

CalculateHMACSHA256()似乎来自盲目复制它,并摆弄所有内容以使编译器满意.但是仍然存在逻辑缺陷.未经测试,我会这样写:

It looks like CalculateHMACSHA256() comes from blindly copying it and just fiddling everything to make the compiler happy. But there are still logical flaws all over. Without testing I'd write it this way:

function GetAuthHeader
( StringToSign: UTF8String  // Expecting an UTF-8 encoded text
; AzureAccountKey: String  // Base64 is ASCII, so text encoding is almost irrelevant
): String;  // Result is ASCII, too, not UTF-8
var
  HMAC: TIdHMACSHA256;
begin
  HMAC:= TIdHMACSHA256.Create;
  try
    // Your key must be treated as pure binary - don't confuse it with
    // a human-readable text-like password. This corresponds to the part
    // "Base64.decode(<your_azure_storage_account_shared_key>)"
    HMAC.Key:= URLEncoding.Base64.DecodeStringToBytes( AzureAccessKey );

    result:= URLEncoding.Base64.EncodeBytesToString  // The part "Signature=Base64(...)"
    ( HMAC.HashValue  // The part "HMAC-SHA256(...,...)"
      ( IndyTextEncoding_UTF8.GetBytes( StringToSign )  // The part "UTF8(StringToSign)"
      )
    );
  finally
    HMAC.Free;
  end;
end;

不能保证,因为我没有机会自己编译它.

No guarantee as I have no chance to compile it myself.

如果在中全部对其进行编码,则在任何地方使用 ToHex()毫无意义.仍然是Base64 .然后,将所有内容都塞进 UTF8String 中也是没有意义的.散列始终意味着使用字节而不是文本-切勿将二进制文件与 String 混用.

Using ToHex() anywhere makes no sense if you encode it all in Base64 anyway. And stuffing everything into UTF8String makes no sense either then. Hashing always implies working with bytes, not text - never mix up binary with String.

这篇关于Base64解码失败,并显示为“目标多字节代码页中不存在Unicode字符的映射".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 21:34