如何在R语言中生成JWS

4
我尝试为Google-oauth2.0 ServiceAccount生成JWT。我设置了头部和有效负载(claim)。但是当我尝试使用RSASHA256签署base64header.base64claim时,我得到了错误的签名。我在PKI包中只找到了一个函数,它允许使用指定的哈希函数用RSA签署内容。
我如何确定我的签名不正确?我发现resource可以从输入和私钥生成JWT。
所以我能看到的是,我的R函数生成的签名与jwt.io的签名不同。我已经使用两个JWT令牌测试了https://www.googleapis.com/oauth2/v3/token的请求,并且jwt.io的那个可以正常工作。
这部分是JWT头。
library(base64enc)
library(jsonlite)
library(PKI)
#JWT header set up
    alg <- "RS256"
    typ <- "JWT"
    header <- list("alg" = alg, "typ" = typ)
    h <- toJSON(header, auto_unbox=TRUE)
    enc.header <- base64encode(charToRaw(h))

这部分是用于JWT声明(负载)的

iss <- "165724828594-mkuchqogmjapbl7mpfn0e7f7o3qlrqsr@developer.gserviceaccount.com"
        scope <- "https://www.googleapis.com/auth/analytics.readonly"
    aud <- "https://www.googleapis.com/oauth2/v3/token"
    iat <- as.integer(as.POSIXct(Sys.time()))
    exp <- iat+3600
    claim <- list("iss" = iss, "scope" = scope, "aud" = aud, "exp" = exp, "iat" = iat)
    cl <- toJSON(claim, auto_unbox=TRUE)
    enc.claim <- base64encode(charToRaw(cl))

这是我的问题。

y <- file("~/keys/euroset-test-70c2d0d4eed1.pem")
key <- PKI.load.key(y)
what <- paste(enc.header,enc.claim, sep=".")
JWS <- PKI.sign(what, key, "SHA256")
enc.sign <- base64encode(JWS)
JWT <- paste(what,enc.sign, sep=".")
JWT

请问有什么需要帮助的吗? 我已经卡在JWS上四天了。
2个回答

0

最后我找到了一个问题点。 它一直与base64编码有关。 我检查了正确和不正确的JWT并发现了一些模式。 不正确的JWT在有效负载和签名中都有"==",我用""替换了它。 此外,在签名中,我将所有"/"替换为"_",所有"+"替换为"-"。 希望这能给遇到同样问题的人一些提示。


0

https://github.com/hadley/httr/blob/master/R/oauth-server-side.R

这是获取令牌的代码,适用于一些 Google API(但不适用于我需要的云..如果您已经使其工作,请告诉我)。此外,httr oauth_service_token 比编写自己的代码要容易得多。

init_oauth_service_account <- function(endpoint, secrets, scope = NULL) {
  signature <- jwt_signature(secrets, scope = scope)

  res <- POST(endpoint$access, body = list(
    grant_type = "urn:ietf:params:oauth:grant-type:jwt-bearer",
    assertion = signature
  ), encode = "form")
  stop_for_status(res)

  content(res, type = "application/json")
}
...
jwt_base64 <- function(x) base64url(jwt_json(x))
jwt_json <- function(x) jsonlite::toJSON(x, auto_unbox = TRUE)
base64url <- function(x) {
  if (is.character(x)) {
    x <- charToRaw(x)
  }
  out <- chartr('+/', '-_', base64enc::base64encode(x))
  gsub("=+$", "", out)
}

感谢提供有用的链接。但是有一个问题,我没有找到如何设置此函数的代理使用。我的工作场所的防火墙不允许我在没有代理设置的情况下发送请求。在httr :: POST中,我能够将代理设置为配置。 out <- chartr('+ /','- _',base64enc :: base64encode(x)) gsub('= + $','',out)这部分告诉我,我的答案是正确的,JWT不正确是因为+/= - Roman Gribov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接