我在 JSON 网络令牌之类的东西中看到的 Base64 和 Base64url 之间有什么区别?
Base64编码可以通过
$ echo Some_data_to_be_converted | base64
U29tZV9kYXRhX3RvX2JlIF9jb252ZXJ0ZWQK
Run Code Online (Sandbox Code Playgroud)
Base64解码可以通过
$ echo U29tZV9kYXRhX3RvX2JlIF9jb252ZXJ0ZWQK | base64 -d
Some_data_to_be_converted
Run Code Online (Sandbox Code Playgroud)
如何实现 Base64URL 编码/解码?
将“+”替换为“-”并将“/”替换为“_”就足够了吗?
什么时候做填充“#”(添加/删除“#”要考虑)?
当我从 JWT 令牌获取一些声明来验证用户身份验证时,出现以下错误:
Illegal base64url character: ' '
Run Code Online (Sandbox Code Playgroud)
创建 JWT 完全没问题,但“解码”似乎有一些问题...我还尝试使用 base64url 解码器在获取声明之前解码令牌,但令牌无效。
我对令牌进行编码和“解码”的 JWToken 类:
@Component
public class JWToken {
private static final String JWT_USERNAME_CLAIM = "sub";
private static final String JWT_ADMIN_CLAIM = "admin";
@Value("${jwt.issuer}")
private String issuer;
@Value("${jwt.passPhrase}")
private String passPhrase;
@Value("${jwt.duration-of-validity}")
private int expiration;
public String encode(String name, boolean admin) {
String token = Jwts.builder()
.claim(JWT_USERNAME_CLAIM, name)
.claim(JWT_ADMIN_CLAIM, admin)
.setSubject(name)
.setIssuer(issuer)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
.signWith(SignatureAlgorithm.HS512, passPhrase).compact();
return token;
}
//for retrieving any …
Run Code Online (Sandbox Code Playgroud) 场景:
我正在此链接 ( https://medium.com/vandium-software/5-easy-steps-to-understanding-json-web-tokens-jwt-1164c0adfcec )阅读有关 JSON 网络令牌的信息。它概述了如何创建 JSON Web 令牌、创建标头和负载,然后使用以下伪代码创建签名:
data = base64urlEncode( header ) + “.” + base64urlEncode( payload )
hashedData = hash( data, secret )
signature = base64urlEncode( hashedData )
Run Code Online (Sandbox Code Playgroud)
我的问题:
为什么base64urlEncode
在创建data
和时使用伪代码signature
?
我目前了解的范围:
Base64 允许您使用来自 Base64 64 个文本字符集的文本字符来表示二进制数据。这通常用于当您有一组数据要通过某些可能会误解某些字符但不会误解 Base64 字符的通道时,因此您使用 Base64 对其进行编码,以便数据不会被误解。另一方面,Base64 URL 编码类似于 Base64 编码,不同之处在于您仅使用 Base64 字符集的一个子集,该子集不包含在 URL 中具有特殊含义的字符,因此如果您在 URL 中使用 Base64 URL 编码字符串URL,它的意思不会被误解。
假设我的理解是正确的,我试图理解为什么base64urlEncode()
在计算data
和signature
上面的伪代码中使用。JSON 网络令牌的签名是否会在 URL 中的某处使用?如果是这样,为什么data
base64urlEncode
d 在散列之前也是如此。为什么不只对签名进行编码?散列函数是否需要将其data …
我将从请求标头中解码 JWT 令牌,它看起来像这样:
eyJzdWIiOiIxIiwiZXZlbnRfaWQiOiI3ZTA3Y2JmNC0wYjYyLTQ1MzMtYmE5ZC1mZGFjNDkyNTNjZTUiLCJpYXQiOiIxNTkwODk4Mzg1IiwiZXhwIjoiMTU5MDkwMTk4NSIImlzcyI6ImxvY2Fsa G9zdDo0NDM4NyIsInRpbWV6b25lX29mZnNldCI6LTcsInVzciI6Im1pbmcuaGlldS4xMzEyIiwiYWxpYXMiOiJNaW5nIEhpZXUiLCJwaG9uZSI6IjA4NDQ1OTAyNTIiLCJlbWFpbCI6ImhpZXVhbWLAZ21ha WwuY29tIn0
public static string Base64Decode(string base64EncodedData)
{
var base64EncodedBytes = Convert.FromBase64String(base64EncodedData);
return Encoding.UTF8.GetString(base64EncodedBytes);
}
Run Code Online (Sandbox Code Playgroud)
当将上面的标记传递给解码方法时,它会抛出一个异常:
Base-64 字符数组或字符串的长度无效
dotnetfiddle 参考: https: //dotnetfiddle.net/Z2TUz9
但是当在javascript中使用它(使用atob函数)时,它可以正常工作。
谁能告诉我为什么,然后告诉我如何用 C# 解码它?
所以,我在网络上和 StackOverflow 上对此做了一些研究,我尝试了很多,我发现的多种建议。问题是我正在登录我们运行良好的 Oauth2 服务之一。我得到了一个 Oath2 JWT 令牌。我知道这是 Base64 编码的,我可以将令牌放入 jwt.io 和 www.base64decode.org,这两个站点都可以正确解析令牌。
我使用的是 Java 8 Base64 工具,代码如下所示:
public String getTokenProperty(String token, String propertyName)
{
byte[] bytes = Base64.getUrlDecoder().decode(token);
String decodedString = new String(bytes, StandardCharsets.UTF_8);
System.out.println("Decoded: " + decodedString);
return (new JSONObject(decodedString)).getString(propertyName);
}
Run Code Online (Sandbox Code Playgroud)
错误发生在解码器线上,如下所示:
java.lang.IllegalArgumentException: Illegal base64 character 2e
Run Code Online (Sandbox Code Playgroud)
我用来自 Oauth2 服务的令牌尝试了这个,我从 Syncope 得到了一个令牌,我从 Auth0 得到了一个令牌......都返回了 JWT Base64 编码的令牌。使用来自这些不同服务器的所有这些令牌,我得到了同样的错误。
我想使用标准的 Java 8 Base64,但我想我可能需要使用外部第三方 Base64 解码器。
任何帮助都会很棒。谢谢!
令牌如下:
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik1qSTRRVFEwT1VRNU9VSXlSVEV6TlRBd05UVXpSVVExTlVOR05FVkVORGRDTlRnM016VXdRZyJ9.eyJodHRwczovL2JpdG9vbXRyYWRlci5uZXQvYXV0aG9yaXphdGlvbiI6eyJncm91cHMiOlsiQ29uc3VtZXJzIl0sInJvbGVzIjpbIlVzZXIiXX0sImlzcyI6Imh0dHBzOi8vYml0em9vbS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NWNhNTE5NzZjYzMzZjUxMTBhYWNkYmM0IiwiYXVkIjpbImh0dHBzOi8vYml0em9vbS5hdXRoMC5jb20vYXBpL3YyLyIsImh0dHBzOi8vYml0em9vbS5hdXRoMC5jb20vdXNlcmluZm8iXSwiaWF0IjoxNTU5MzIzNDI1LCJleHAiOjE1NTk0MDk4MjUsImF6cCI6IlliRGFSelRVQkFtZEFrSExqdjZ0bEI3U05xSTF1RlNtIiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCBhZGRyZXNzIHBob25lIHJlYWQ6Y3VycmVudF91c2VyIHVwZGF0ZTpjdXJyZW50X3VzZXJfbWV0YWRhdGEgZGVsZXRlOmN1cnJlbnRfdXNlcl9tZXRhZGF0YSBjcmVhdGU6Y3VycmVudF91c2VyX21ldGFkYXRhIGNyZWF0ZTpjdXJyZW50X3VzZXJfZGV2aWNlX2NyZWRlbnRpYWxzIGRlbGV0ZTpjdXJyZW50X3VzZXJfZGV2aWNlX2NyZWRlbnRpYWxzIHVwZGF0ZTpjdXJyZW50X3VzZXJfaWRlbnRpdGllcyIsImd0eSI6InBhc3N3b3JkIn0.St7097L1ZAlBWcAPrie-8CGV2F3Fr8uNYpSDVKSPVPF4zBZrmm62_UAj7Ssux8AjUy0LhjiF3kLpNph2L7yrpUREw6TyGJwQasfdVtM5VzRYUcy-fOGyRSqPQorbzxJQZzs2pyDJm-2hMQ0McJ37ubKIWrHFD5McMedN6THK7g5TExX47XCRPcOuCEWm3bf3zdWF2LEGhCw_c-lcZDwlb4ePkO721XjSWtrXEBvxc8scFNaHDt7VOnrSze4XK_LO8eE8bHRq6qUrWf1csYucK--aHazBsvfdl-6QDRk-tOBM-LdXJMT7H8Ih6trxVmZofQjr2dQ4j_3DTVoU3eLdog
Run Code Online (Sandbox Code Playgroud)
更新:
我从 java,util.Base64 切换到 org.apache.commons.codec.binary.Base64 并且这似乎有点工作,我现在没有收到错误。
String decodedString = new String(bytes, StandardCharsets.UTF_8); …
Run Code Online (Sandbox Code Playgroud) 编辑 1
这与浏览器无关。如果我没有登录,就会发生这种情况。当我登录时,它运行良好。抱歉匆忙。
我知道这很奇怪并且没有任何意义也很难解释。
正如标题所说,浏览器会导致此问题,但我不确定。
所以我有一个图像服务,它从某个地方读取一些数据并通过读取的数据创建图像。然后它会做一些事情并以 base64 格式返回图像,以便我可以在我的网站中使用这些图像。当我在我的网站上打开一个页面时,这个过程就开始了。
问题是,如果我在 Safari 上打开页面,它可以正常工作,但今天我尝试在 Chrome 上打开页面,但图像没有加载。所以我检查了图像,发现没有data
数据 URI 的开头属性。
让我用一个例子来解释;
这是我在创建 HTML 模板时的代码
presets += `<div class="icon"> <img src="data:image/png;base64,${icon}"></div>`
presets += `<p class="name">${name}</p>`
presets += `<div class="image"> <img src="data:image/png;base64,${image}"/></div>`
Run Code Online (Sandbox Code Playgroud)
我正在做一些事情,然后返回这些数据,在 postman 和 safari 上我得到了这个结果:
<div class="icon"> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA{ ... }"></div>
Run Code Online (Sandbox Code Playgroud)
所以这很好。没有什么不对的。
但是当我在 Chrome 或 Opera 上打开页面时,我得到了这个;
<div class="icon"> <img src="image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA{ ... }"></div>
Run Code Online (Sandbox Code Playgroud)
看?没有data
属性。我正在 Wordpress 中插入一个帖子,这是帖子的内容。为什么会这样?我希望我已经清楚地解释了我自己。
编辑 2
这是我用来插入帖子的功能
function programmatically_create_post($title, $content, $slug)
{
// Setup the author,
$author_id = 4; …
Run Code Online (Sandbox Code Playgroud) 我想在Flutter中的Base64Url中编码以下字符串,然后在Dart服务器上对其进行解码。
"username:password"
Run Code Online (Sandbox Code Playgroud)
我怎么做?以及如何在Base64中做到这一点?