這裡記錄我在使用 js 的 base64 解密功能時,因為 UTF-8 編碼與 base64 格式,會遇到的問題
這是我要進行 base64 加密的字串
{"id":"e0405f3f-e0b3-4eb8-a1ed-b9cc63dfe6de","userName":"司馬曉明","account": "sma","email": "light.sma@example.foo.org","iat": 1754621860,"exp": 1754622760}
這是該字串用 Go 各種 base64 加密方式加密後的結果
- base64.RawStdEncoding
- eyJpZCI6ImUwNDA1ZjNmLWUwYjMtNGViOC1hMWVkLWI5Y2M2M2RmZTZkZSIsInVzZXJOYW1lIjoi5Y+46aas5puJ5piOIiwiYWNjb3VudCI6ICJzbWEiLCJlbWFpbCI6ICJsaWdodC5zbWFAZXhhbXBsZS5mb28ub3JnIiwiaWF0IjogMTc1NDYyMTg2MCwiZXhwIjogMTc1NDYyMjc2MH0
- base64.RawURLEncoding
- eyJpZCI6ImUwNDA1ZjNmLWUwYjMtNGViOC1hMWVkLWI5Y2M2M2RmZTZkZSIsInVzZXJOYW1lIjoi5Y-46aas5puJ5piOIiwiYWNjb3VudCI6ICJzbWEiLCJlbWFpbCI6ICJsaWdodC5zbWFAZXhhbXBsZS5mb28ub3JnIiwiaWF0IjogMTc1NDYyMTg2MCwiZXhwIjogMTc1NDYyMjc2MH0
- base64.StdEncoding
- eyJpZCI6ImUwNDA1ZjNmLWUwYjMtNGViOC1hMWVkLWI5Y2M2M2RmZTZkZSIsInVzZXJOYW1lIjoi5Y+46aas5puJ5piOIiwiYWNjb3VudCI6ICJzbWEiLCJlbWFpbCI6ICJsaWdodC5zbWFAZXhhbXBsZS5mb28ub3JnIiwiaWF0IjogMTc1NDYyMTg2MCwiZXhwIjogMTc1NDYyMjc2MH0=
- base64.URLEncoding
- eyJpZCI6ImUwNDA1ZjNmLWUwYjMtNGViOC1hMWVkLWI5Y2M2M2RmZTZkZSIsInVzZXJOYW1lIjoi5Y-46aas5puJ5piOIiwiYWNjb3VudCI6ICJzbWEiLCJlbWFpbCI6ICJsaWdodC5zbWFAZXhhbXBsZS5mb28ub3JnIiwiaWF0IjogMTc1NDYyMTg2MCwiZXhwIjogMTc1NDYyMjc2MH0=
而這幾個方式得到的 base64 加密字串,base64.RawStdEncoding和base64.StdEncoding是可以用 javascript 的 atob() function 解密的
只是解密出來的字串,由於編碼的關係,非 ASCII 字元都會出錯
以上述例子來說,userName 會變成 "å\u008f¸é¦¬æ\u009b\u0089æ\u0098\u008e"
解決
要使這四種都能正常解密
首先,先將 URL safe 的Base64 字串改成一般的
function(base64Str: string): string{
let result = base64Str.replace(/-/g, '+').replace(/_/g, '/')
while (result.length % 4 !== 0) {
result += '='
}
return result
}
然後處理解密後的文字,改成 UTF-8 編碼
function(base64Str: string): string{
const decodedData: string = atob(base64Str)
// 轉成 byte array
const bytes = new Uint8Array(
decodedData.split("").map(function(ch){ // 如果是 ES2015 以上的版本,也可以寫成 [...decodedData].map(...)
return ch.charCodeAt(0)
})
)
return new TextDecoder('utf-8').decode(bytes)
}
這樣四種字串都能正常運作了
參考資料
Josefsson, S. (2006). The Base16, Base32, and Base64 Data Encodings. RFC Editor. https://doi.org/10.17487/RFC4648
Window: atob() method - Web APIs. (2025, June 24). MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/API/Window/atob
JavaScript 中的 Base64 編碼字串細微差異. (2023, October 17). web.dev. https://web.dev/articles/base64-encoding?hl=zh-tw
沒有留言:
張貼留言