Предположим, у меня есть следующий JWK
в качестве десериализованного тела некоторого JWS
(RFC7515), где модуль n
частично опущен для отображения
{
"kty": "RSA",
"e": "AQAB",
"kid": "KAgNpWbRyy9Mf2rikl498LThMrvkbZWHVSQOBC4VHU4",
"n": "llWmHF8XA2KNLdmxOP3kxD9OY76p0Sr37j..."
}
Заголовок JWS
определяет поля alg
и kid
, необходимые для проверки подписи.
Как мне создать открытый ключ RSA из этого JWK
, чтобы я мог проверить подпись? Посмотрев на некоторые связанные questions, у меня есть следующая реализация Java, которая пытается создать открытый ключ RSA из n
и e
поля в 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 в приведенном выше коде каким-то образом неверен. Любая помощь приветствуется.
ИЗМЕНИТЬ
Библиотека JSON Gson
JWK
библиотека - это nismus-jose-jwt
, которая предоставляет Base64
и Base64URl
Base64
,Base64URL
и вашу библиотеку JWK / JSON отсутствуют, а такжеparts
не объяснены. При условии правильного декодирования Base64urln
иe
будет сгенерирован правильный ключ. Предположительноparts[0]
,parts[1]
иparts[2]
содержат заголовок, полезную нагрузку и подпись, каждый из которых закодирован в Base64url. Подпись должна быть декодирована Base64 url для вызоваverify()
, но, похоже, декодируется только Base64, так что, возможно, это проблема (хотя я ожидал бы здесь исключения). Пожалуйста, добавьте недостающую информацию. - person user 9014097   schedule 26.02.2021parts
- этоString[]
, состоящий из заголовка, полезной нагрузки и подписи. Обновлен вопрос, чтобы включить библиотеки. - person Scott   schedule 26.02.2021parts[2]
с помощью Base64url вместо Base64? - person user 9014097   schedule 26.02.2021false
изverify()
- person Scott   schedule 26.02.2021n
иe
указаны вJWK
, так что я могу получить ключ из этого, не так ли? - person Scott   schedule 26.02.2021