使用RSA私钥在Powershell中将JSON Web令牌加密为RSA RS256

时间:2019-09-17 06:36:15

标签: powershell encryption jwt rsa docusignapi

我被困住了,我正在尝试为Docusign签名Json Web令牌。 https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-jsonwebtoken Docusign仅提供RSA私钥和公钥哈希。而已。 JWT必须使用RS256签名。

我找到了JWT模块https://www.powershellgallery.com/packages/JWT/1.1.0,但这需要安装证书。但是我所拥有的只是密钥哈希。

利用其他一些代码,我发现我可以创建JWT令牌,尽管算法错误。 https://www.reddit.com/r/PowerShell/comments/8bc3rb/generate_jwt_json_web_token_in_powershell/ 我一直在尝试通过创建新对象来对其进行修改,以使用RSACryto提供程序,但我一直没有成功。

我试图创建一个新对象,看看是否可以导入密钥,以便对令牌进行签名。但我似乎无法做到这一点。

$rsa = New-Object -TypeName System.Security.Cryptography.RSACryptoServiceProvider
$keyhash = "-----BEGIN RSA PRIVATE KEY-----
XXXXXX
-----END RSA PRIVATE KEY-----"

$blob = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($keyhash))

我尝试使用ImportCspBlob方法,但它要求将字符串转换为字节,但我似乎也不能这样做。

我不确定我是否正在采用这种正确的方式。我一直都收到错误消息

Exception calling "ImportCspBlob" with "1" argument(s): "Bad Version of provider.
or
Cannot convert value to type "System.Byte". Error: "Input string was not in a correct format."

编辑: 尽管id仍然想看看是否有可能做我在Powershell中尝试做的事情,但我仍在使用Node.js进行工作。这项工作对于某些人可能有用,因为使用Powershell和Docusign API的引用似乎并不多。

我在这里找到了一个node.JS脚本,该脚本使用RS256算法创建了JWT令牌。 https://github.com/BlitzkriegSoftware/NodejwtRSA

我剔除了所有多余的东西,所以控制台的输出只是令牌,并将相关范围添加到“有效载荷数据”,并在符号选项下更新了sub,aud和iss。我的RSA私钥在文件中本地存储在系统中。

nodejs脚本-下面的我的修改版本

'use strict';

const path = require('path');
const fs = require('fs');

// https://github.com/auth0/node-jsonwebtoken
var jwt = require('jsonwebtoken');

// Private Key (must read as utf8)
var privateKey = fs.readFileSync('./rsatest.pk','utf8');
// Sample claims payload with user defined fields (this can be anything, but briefer is better):
var payload = { };
// Populate with fields and data
payload.scope = "signature impersonation";
// Values for the rfc7519 fields
var iss = "XXXXX-XXXX-XXX-XXX-XXX";
var sub = "XXXXX-XXXX-XXX-XXX-XXX";
var aud = "account-d.docusign.com";
// Expiration timespan: https://github.com/auth0/node-jsonwebtoken#token-expiration-exp-claim
var exp = "1h";
// JWT Token Options, see: https://tools.ietf.org/html/rfc7519#section-4.1 for the meaning of these
// Notice the `algorithm: "RS256"` which goes with public/private keys
var signOptions = {
    issuer : iss,
    subject: sub,
    audience: aud,
    expiresIn: exp,
    algorithm: "RS256"
};
var token = jwt.sign(payload, privateKey, signOptions);
console.log(token)
process.exitCode = 0;

我从Powershell调用了它,并将访问令牌反馈回脚本中,这样我就可以获取访问令牌并开始进行API调用。

#get the JWT token
$token = & node C:\temp\nodejwt.js
# Generate Header for API calls.
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", "application/x-www-form-urlencoded")
$body ="grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=$token"
$authuri = "https://account-d.docusign.com/oauth/token"
#send the JWT and get the access token 
$accesstoken = Invoke-RestMethod -Method post -Uri $authuri -Headers $headers -Body $body -Verbose
$getheaders = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$getheaders.Add("Content-Type", "application/json")
$getheaders.Add('Authorization','Bearer ' + $accesstoken.access_token)    
$geturi = "https://account-d.docusign.com/oauth/userinfo"
#use the access token to make api calls 
Invoke-RestMethod -Method get -Uri $geturi -Headers $getheaders 

1 个答案:

答案 0 :(得分:0)

我也遇到了同样的问题并且被卡住了。我使用Python来获取JWT。确保安装PyJWT和加密库。

$ pip install PyJWT
$ pip install pyjwt[crypto]


import time
import jwt
from datetime import datetime, timedelta

private_key= b'-----BEGIN PRIVATE KEY-----
`-----END PRIVATE KEY-----\n'

encoded_jwt = jwt.encode({
    "iss":"<service account e-mail>",
    "scope":"",
    "aud":"",
    "exp":int(time.time())+3600,
    "iat":int(time.time())
    }, private_key, algorithm='RS256')
encoded_jwt