从JWK生成公钥 [英] Generating Public Key from JWK

查看:231
本文介绍了从JWK生成公钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下 JWK 作为某些 JWS (RFC7515),出于显示目的,模数 n 被部分省略

Suppose I have the following JWK as the deserialised body of some JWS (RFC7515), where the modulus n is partially omitted for display purposes

{
   "kty": "RSA",
   "e": "AQAB",
   "kid": "KAgNpWbRyy9Mf2rikl498LThMrvkbZWHVSQOBC4VHU4",
   "n": "llWmHF8XA2KNLdmxOP3kxD9OY76p0Sr37j..."
}

JWS 标头指定签名验证所需的 alg kid 字段.

And the JWS header specifies both the alg and kid fields required for signature verification.

如何从此 JWK 构建RSA公钥,以便可以验证签名?看过一些相关

How do I construct an RSA public key from this JWK so that I can verify the signature? Having looked at some related questions, I have the following Java implementation that attempts to build an RSA public key from the n and e fields within the JWK

public void someMethod(){
    String exjws ="eyJhbGciOiJSUzI1NiIsImtpZCI6IktBZ05wV2JSeXk5TWYycmlrbDQ5OExUaE1ydmtiWldIVlNRT0JDNFZIVTQiL"
        + "CJodG0iOiJwb3N0IiwiaHR1IjoiL3R4IiwidHMiOjE2MDM4MDA3ODN9.eyJjYXBhYmlsaXRpZXMiOltdLCJjbGllbnQiOnsia2V5Ijp7Imp3ayI6eyJrdHkiOiJSU0EiLCJ"
        + "hbGciOiJSUzI1NiIsImUiOiJBUUFCIiwia2lkIjoiS0FnTnBXYlJ5eTlNZjJyaW"
        + "tsNDk4TFRoTXJ2a2JaV0hWU1FPQkM0VkhVNCIsIm4iOiJsbFdtSEY4WEEyS05MZG14T1Aza3hEOU9ZNzZwMFNyMzdqZmh6OTRhOTN4bTJGTnFvU1BjUlpBUGQwbHFEUzhO"
        + "M1VpYTUzZEIyM1o1OU93WTRicE1fVmY4R0p2dnB0TFdueG8xUHlobVByIC0gZWNkU0NSUWRUY19aY01GNGhSVjQ4cXFsdnVEMG1xdGNEYklrU0JEdmNjSm1aSHdmVHBESG"
        + "luVDh0dHZjVlA4VmtBTUFxNGtWYXp4T3BNb0lSc295RXBfZUNlNXBTd3FIbzBkYUNXTktSI"
        + "C0gRXBLbTZOaU90ZWRGNE91bXQ4TkxLVFZqZllnRkhlQkRk"
        + "Q2JyckVUZDR2Qk13RHRBbmpQcjNDVkN3d3gyYkFRVDZTbHhGSjNmajJoaHlJcHE3cGM4clppYjVqTnlYS3dmQnVrVFZZWm96a3NodCAtIExvaHlBU2FLcFlUcDhMdE5aIC0gdyAifSw"
        + "icHJvb2YiOiJqd3MifSwibmFtZSI6Ik15IEZpcnN0IENsaWVu"
        + "dCIsInVyaSI6Imh0dHA6XC9cL2xvY2FsaG9zdFwvY2xpZW50XC9jbGllbnRJRCJ9LCJpbnRlcmFjdCI6eyJzdGFydCI6WyJyZWRpcmVjdCJ"
        + "dLCJmaW5pc2giOnsibWV0aG9kIjoicmVkaXJlY3QiLCJub25jZSI6ImQ5MDIxMzg4NGI4NDA5MjA1MzhiNWM1MSIsInVyaSI6Imh0dHA6XC9cL2xvY2FsaG9zdFwvY2xpZW50"
        + "XC9yZXF1ZXN0LWRvbmUifX0sImFjY2Vzc190b2tlbiI6eyJhY2Nlc3MiOlt7ImFjdGlvbnMiOlsicmVhZCIsInByaW50Il0sImxvY2F0aW9ucyI6WyJodHRwOlwvXC9sb2Nhb"
        + "Ghvc3RcL3Bob3RvcyJdLCJkYXRhdHlwZXMiOlsibWV0YWRhdGEiLCJpbWFnZXMiXSwidHlwZSI6InBob3RvLWFwaSJ9XX0sInN1YmplY3QiOnsic3ViX2lkcyI6WyJpc3Nfc3"
        + "ViIiwiZW1haWwiXX19.LUyZ8_fERmxbYARq8kBYMwzcd8GnCAKAlo2ZSYLRRNAYWPrp2XGLJOvg97WK1idf_LB08OJmLVsCXxCvn9mgaAkYNL_ZjHcusBvY1mNo0E1sdTEr31"
        + "CVKfC-6WrZCscb8YqE4Ayhh0Te8kzSng3OkLdy7xN4xeKuHzpF7yGsM52JZ0cBcTo6WrYEfGdr08AWQJ59ht72n3jTsmYNy9A6I4Wrvfgj3TNxmwYojpBAi"
        + "cfjnzA1UVcNm9F_xiSz1_y2tdH7j5rVqBMQife-k9Ewk95vr3lurthenliYSNiUinVfoW1ybnaIBcTtP1_YCxg_h1y-B5uZEvYNGCuoCqa6IQ";

    String[] parts = exjws.split("\\.");
    String payload = new Base64URL(parts[1]).decodeToString();
    JsonObject jwk  = JsonParser.parseString(payload).getAsJsonObject().get("client")
            .getAsJsonObject().get("key").getAsJsonObject().get("jwk").getAsJsonObject();

    BigInteger modulus = new BigInteger(1, new Base64URL(jwk.get("n").getAsString()).decode());  
    BigInteger exponent = new BigInteger(1, new Base64URL(jwk.get("e").getAsString()).decode());
    byte[] signingInfo = String.join(".",parts[0],parts[1]).getBytes(StandardCharsets.UTF_8);
    byte[] b64DecodedSig = new Base64(parts[2]).decode();
    
    PublicKey pub = KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(modulus, exponent));
    
    Signature verifier = Signature.getInstance("SHA256withRSA");    
    verifier.initVerify(pub);
    verifier.update(signingInfo);
    boolean okay = verifier.verify(b64DecodedSig);
    System.out.println(okay);
}

verify()的结果当前返回 false .

我尝试生成RSA密钥对,并使用生成的密钥和有效的进行签名和验证.我怀疑我的问题是上面代码中构造的RSA密钥以某种方式是错误的.任何帮助表示赞赏.

I have tried generating RSA key pairs, signing and verifying using the generate keys and that worked. I suspect that my issue is that the constructed RSA key in the code above is wrong somehow. Any help appreciated.

编辑

JSON库是 Gson

JWK 库是 nismus-jose-jwt ,它提供 Base64 Base64URl

推荐答案

摘自与@Topaco的讨论:

From the discussion with @Topaco in the comments:

问题中的代码确实通过模数 n 和指数 e 成功构建了RSA公钥.

The code in the question does successfully construct the RSA public key from the modulus n and the exponent e.

但是,由于请求中 JWK 中指定的公钥与 Signature.verify()调用返回 false ,因此返回 false .用于签署请求的密钥.

However, the Signature.verify() invocation returns false because the public key specified within the JWK in the request does not match the key used to sign the request.

这篇关于从JWK生成公钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆