我需要先加密然后对字符串进行base64编码,以使用Twitter的OAuth 1.1 API进行身份验证。
我正在设计的平台提供了HMAC功能,因此第一部分还不错。但是,当我尝试对结果进行Base64编码时,它是对十六进制表示而不是HMAC哈希输出的字节码版本进行编码。
我的工作示例使用CryptoJS,但没有它,我需要获得相同的结果,但是使用btoa
会得到不同的结果。
当前工作代码,使用CryptoJS进行HMAC,然后使用Base64编码:
const encrypted = CryptoJS.HmacSHA1("message", "secret");
const encoded = CryptoJS.enc.Base64.stringify(encrypted)
console.log(encrypted);
// encrypted = "0caf649feee4953d87bf903ac1176c45e028df16"
console.log(encoded);
// encoded = DK9kn+7klT2Hv5A6wRdsReAo3xY=
我已经能够通过在Python(我的首选语言)中复制代码来进行调试,并且可以看到“加密”版本是十六进制字符串,这就是为什么我尝试过的“内置”版本没有工作。
编辑:为btoa
添加了代码,这为我所需提供了错误的输出。与上面encoded
的输出进行比较:
console.log(btoa(encrypted));
// btoa_version = "MGNhZjY0OWZlZWU0OTUzZDg3YmY5MDNhYzExNzZjNDVlMDI4ZGYxNg=="
您可以尝试使用浏览器中的base64编码功能来进行此操作
const encrypted = CryptoJS.HmacSHA1("message", "secret");
var encoded;
var b = new Blob([encrypted ])
var reader = new FileReader();
reader.onload = function(e){
encoded = e.target.result.split(',')[1];
};
reader.readAsDataURL(b);
console.log(encoded);
使用borismus's代码段正确解码base64
/* borismus's decode function */
var BASE64_MARKER = ';base64,';
function convertDataURIToBinary(dataURI) {
var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
var base64 = dataURI.substring(base64Index);
var raw = window.atob(base64);
var rawLength = raw.length;
var array = new Uint8Array(new ArrayBuffer(rawLength));
for(i = 0; i < rawLength; i++) {
array[i] = raw.charCodeAt(i);
}
return array;
}
const encrypted = CryptoJS.HmacSHA1("message", "secret");
var encoded;
var b = new Blob([encrypted ])
// use Filereader's base64 feature
var reader = new FileReader();
reader.onload = function(e){
encoded = e.target.result ;
var str = convertDataURIToBinary(encoded);
encoded = new TextDecoder("utf-8").decode(str);
console.log(encoded); // 0caf649feee4953d87bf903ac1176c45e028df16
};
reader.readAsDataURL(b);