使用 BouncyCastle (C#) 签署数据并使用 jsrsasign (js) 验证

Sign data with BouncyCastle (C#) and verify with jsrsasign (js)

我正在尝试在服务器端签署数据并在客户端验证它。 密钥 - private 和 public 在客户端(public)和服务器(private)上都保存为 PEM 字符串。

当我在服务器或客户端执行所有操作时,一切正常 - 签名和验证。

服务端代码:

// Prepare data to sign as bytes[]
byte[] dataToSign = Encoding.UTF8.GetBytes(data);

var keyParamAsPEM = (AsymmetricCipherKeyPair)pemReader.ReadObject();
AsymmetricKeyParameter key = keyParamAsPEM.Private;

var keyParameter = new RsaKeyParameters(key.IsPrivate, ((RsaPrivateCrtKeyParameters) key).Modulus, ((RsaPrivateCrtKeyParameters) key).Exponent);

// Init alg
ISigner sig = SignerUtilities.GetSigner("SHA256withRSA");

// Populate key
sig.Init(true, keyParameter);

// Calc signature
sig.BlockUpdate(dataToSign, 0, dataToSign.Length);
byte[] signature = sig.GenerateSignature();

// Base 64 encode the sig so its 8-bit clean
string signatureServer = Convert.ToBase64String(signature);

客户端代码:

const pubKey = rsa.KEYUTIL.getKey(PUBLIC_KEY);
const rsaObj = new rsa.Signature({ alg: 'SHA256withRSA' });
rsaObj.init(pubKey);
rsaObj.updateString(JSON.stringify(data));
const isValid = rsaObj.verify(signature);

我在客户端签了数据:

const privKey = rsa.KEYUTIL.getKey(PRIVATE_KEY);
const sig = new rsa.Signature({ alg: 'SHA256withRSA' });
sig.init(privKey);
sig.updateString(JSON.stringify(data));
const signatureClient = sig.sign();

而且我发现signatureClient(在客户端创建的签名)不等于signatureServer(签名在服务器端创建)。

问题已解决。

我在服务器端使用 JOSE-JWT dll 和 Bouncy Castle 对数据进行签名。我在声明部分的 'sub' 属性 中存储数据时创建了一个令牌。

在客户端,我仍在使用 jsrsasign 包,但我现在正在使用 jws.JWS.verifyJWT() 方法验证令牌。