简体   繁体   English

无法使用已配置的PublicKey验证RSA签名。 签名长度不正确:达到255,但预期为256

[英]Unable to verify RSA signature using configured PublicKey. Signature length not correct: got 255 but was expecting 256

I am trying to learn how to use RSA public-private key pair to sign JWT. 我正在尝试学习如何使用RSA公私钥对对JWT进行签名。

I generated key pair using openssl . 我使用openssl生成了密钥对。

openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048

openssl rsa -pubout -in private_key.pem -out public_key.pem

I am setting environment varibles as below 我正在如下设置环境变量

export PRIVATE_KEY_DEMO=`cat private_key.pem`

export PUBLIC_KEY_DEMO=`cat public_key.pem`

I have following functions that create PrivateKey and PublicKey 我有以下创建PrivateKeyPublicKey函数

public PrivateKey getPrivateKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, URISyntaxException {
    String key = env.getProperty("PRIVATE_KEY_DEMO");
    key = key.replace("-----BEGIN PRIVATE KEY-----", "")
         .replace("-----END PRIVATE KEY-----", "")
         .replace("\n", "");

    byte[] keyBytes = Base64.getMimeDecoder().decode(key);

    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return kf.generatePrivate(spec);
}

private PublicKey getPublicKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, URISyntaxException {

    String key = env.getProperty("PUBLIC_KEY_DEMO");
    key = key.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLICKEY-----", "").replace("\n", "");
    byte[] keyBytes = Base64.getMimeDecoder().decode(key);

    X509EncodedKeySpec spec = new X509EncodedKeySpec((keyBytes));
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return kf.generatePublic(spec);
}

I am able to get JWT token, however, I am not able to generate PublicKey Below is ExceptionStack: 我可以获取JWT令牌,但是无法生成PublicKey下面是ExceptionStack:

java.security.SignatureException: Signature length not correct: got 255 but was expecting 256
    at sun.security.rsa.RSASignature.engineVerify(RSASignature.java:189) ~[na:1.8.0_191]
    at java.security.Signature$Delegate.engineVerify(Signature.java:1222) ~[na:1.8.0_191]
    at java.security.Signature.verify(Signature.java:655) ~[na:1.8.0_191]
    at io.jsonwebtoken.impl.crypto.RsaSignatureValidator.doVerify(RsaSignatureValidator.java:63) ~[jjwt-0.9.1.jar:0.9.1]
    at io.jsonwebtoken.impl.crypto.RsaSignatureValidator.isValid(RsaSignatureValidator.java:47) ~[jjwt-0.9.1.jar:0.9.1]
    at io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator.isValid(DefaultJwtSignatureValidator.java:47) ~[jjwt-0.9.1.jar:0.9.1]
    at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:351) ~[jjwt-0.9.1.jar:0.9.1]

Please let me know what am I doing wrong and if it can be implemented in better way. 请让我知道我在做什么错,以及是否可以更好地实施。


Edit 编辑

Below are the methods I am using to generate/validate JWT. 以下是我用来生成/验证JWT的方法。

public String generateToken()
        throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, URISyntaxException {

    PrivateKey privateKey = this.getPrivateKey();

    Date date = new Date();
    date.setTime(date.getTime() + 60 * 60 * 1000);
    String jws;

    jws = Jwts.builder()
                .setAudience("jws-consumers")
                .setIssuer("jws-issuer")
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "RS256")
                .setExpiration(date)
                .setIssuedAt(new Date())
                .setSubject("nish")
                .signWith(SignatureAlgorithm.RS256, privateKey)
                .compact();
    return jws;
}

public Object validateToken(String token) throws ExpiredJwtException, MalformedJwtException, SignatureException,
        IllegalArgumentException, NoSuchAlgorithmException, InvalidKeySpecException, IOException, URISyntaxException {
    return Jwts.parser()
            .setSigningKey(getPublicKey())
            .parse(token)
            .getBody();
}

Here is a sample of generated JWT 这是生成的JWT的示例

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJqd3MtY29uc3VtZXJzIiwiaXNzIjoiandzLWlzc3VlciIsImV4cCI6MTU1MDE2NDc0NCwiaWF0IjoxNTUwMTYxMTQ0LCJzdWIiOiJuaXNoIn0.EbNzMIUc4HE6CwIDyURdYF-tE4z7rzM9_GbHpB-TlRror9HRO5bmGgXR7x9HOazmL3cTUPMd46s7QJ9cU_HIJYQu9pYIQzu3V2WZf0zpFevtFxBbGDU_UCM1fbdsgSrd8APSKt_mXbJGdzIA8L7O6gBnpvNowgEuNHYgMiRwL89GrT17c31WwIWSRfRubn-bYU62pd5wm5pMArvGBYi6f6EAoIdYsK-nlhKjOIsxjGigjYAohoooV_xv36_q5_8Iaxppl2yroxCeYCy6Jp9po3bjoLVu3k9vkD_-yUGoXr9e-LCktSS4Ndxq4KCVRI_Cf5Ix_ImcZrqFZLdb4UWGmA

GitHub GitHub上

In case anyone is having same problem, I solved this by following example . 如果有人遇到相同的问题,我将通过以下示例来解决。

I generated my public / private keys using commands shown here . 我使用此处显示的命令生成了public / private密钥。

and changed following lines (use PRIVATE instead of PUBLIC for PRIVATE key) 并更改了以下几行(使用PRIVATE而不是PUBLIC作为PRIVATE密钥)

key = key.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLICKEY-----", "").replace("\n", "");

to

key = key.replaceAll("\\n", "").replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "");

It did the magic and works perfectly fine. 它起到了神奇的作用,并且效果很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Signature.verify 抛出异常 Signature length not correct: got 248 but was expected 256 - Signature.verify is throwing an exception Signature length not correct: got 248 but was expecting 256 数字签名错误-签名长度不正确:达到344,但预期为256 - Digital Signature error - Signature length not correct: got 344 but was expecting 256 签名长度不正确:得到768但是在Java验证中期望为512 - Signature length not correct: got 768 but was expecting 512, in Java verify 签名长度不正确:得到127但是期待128 - Signature length not correct: got 127 but was expecting 128 DockerforWindows :JenkinsInstallation:java.security.SignatureException:签名长度不正确:得到 512 但期待 256 - DockerforWindows : JenkinsInstallation : java.security.SignatureException: Signature length not correct: got 512 but was expecting 256 RSA SignatureException:签名长度不正确 - RSA SignatureException: Signature length not correct 验证 C# 中的 RSA SHA256 签名 - Verify RSA SHA256 signature in C# 无法在Android上验证rsa签名 - Cannot verify rsa signature on Android 如何使用RSA256算法生成JWT签名? - How to generate JWT-Signature using RSA256 algorithm? javax.xml.crypto.dsig.XMLSignatureException:java.security.SignatureException:签名长度不正确:得到128但期待512 - javax.xml.crypto.dsig.XMLSignatureException: java.security.SignatureException: Signature length not correct: got 128 but was expecting 512
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM