2017-06-19 38 views
5

Tôi muốn xác minh chữ ký của một số JWT từ Microsoft. Tôi đang sử dụng Spring-Boot, thư viện JJWT và điểm cuối sau: https://login.microsoftonline.com/common/discovery/v2.0/keysXác minh Chữ ký JWT bằng cách sử dụng điểm cuối khóa công khai

Điểm cuối trả về một mảng khóa công cộng JSON. Đây là một ví dụ từ mảng.

{ 
      "kty": "RSA", 
      "use": "sig", 
      "kid": "9FXDpbfMFT2SvQuXh846YTwEIBw", 
      "x5t": "9FXDpbfMFT2SvQuXh846YTwEIBw", 
      "n": "kvt1VmR4nwkNM8jMU0wmj2gSS8NznbOt2pZI6Z7HQT_esF7W19GZR7Y72Xo1i5zXRDM9o3GeTIjBrnr3yy41Q_EaUQ7C-b-Hmg94Vy7EBZyBhi_mznz0dYWs2MIXwR86Nni9TmgTXvjgTPF2YGJoZt4TwcMFefW8rijCVyNrCBA0XspDouNJavvG0BEMXYigoThFjLRXS5U3h4BDfNZFZZS3dyliNOXfgRn2k7oITz8h_ueiPvmDRFh38AeQgx1cELhKWc3P5ugtttraSwgH7nP2NUguO9nCrHuL6TZ-KWpmRWZqwH-jYKFQVt3CDpzwNM6XJL-oHbl1x-gI3YYX5w", 
      "e": "AQAB", 
      "x5c": [ 
       "MIIDBTCCAe2gAwIBAgIQZSAeaqWig4BHC1ksmNNcgjANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTE3MDUwNjAwMDAwMFoXDTE5MDUwNzAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJL7dVZkeJ8JDTPIzFNMJo9oEkvDc52zrdqWSOmex0E/3rBe1tfRmUe2O9l6NYuc10QzPaNxnkyIwa5698suNUPxGlEOwvm/h5oPeFcuxAWcgYYv5s589HWFrNjCF8EfOjZ4vU5oE1744EzxdmBiaGbeE8HDBXn1vK4owlcjawgQNF7KQ6LjSWr7xtARDF2IoKE4RYy0V0uVN4eAQ3zWRWWUt3cpYjTl34EZ9pO6CE8/If7noj75g0RYd/AHkIMdXBC4SlnNz+boLbba2ksIB+5z9jVILjvZwqx7i+k2filqZkVmasB/o2ChUFbdwg6c8DTOlyS/qB25dcfoCN2GF+cCAwEAAaMhMB8wHQYDVR0OBBYEFGKpXQNrF5IoxS6bL4F92+gxOJlIMA0GCSqGSIb3DQEBCwUAA4IBAQA3HgW5SoHlvvQVxqqi+mtscDZLhNfe13iG/nx8Er5il82b79RVydNs+f9sYxc4T4ctnrZu7x5e7jInJedNdAlrPorBdw+SfvKJsmiNndXugMew1FlcQTQVIFDCbziaJav8rKyMxPfeKkc1aixbajWZkKg6OPmmJn2ceTocbn8PMQy20xNvcWUwgF5FZZIuPqu6feOLJcUIYw+0JFZ265xka30QXpmytcIxajIzpD4PRdCIBuVSqgXacAs4t4+w+OhnosD72yvXck8M4GwX1j+vcuyw0yhDGNMmqsHWP7H3jnJiGDrKhhdVyplzDhTfv2Whbv/dIDn+meLE3yyC5yGL" 
      ], 
      "issuer": "https://login.microsoftonline.com/{tenantid}/v2.0" 
     } 

Trong JJWT, tôi đã triển khai giao diện SigningKeyResolver và tôi được yêu cầu trả lại phiên bản RSAPublicKey để thực hiện xác minh. Sự cố tôi đang gặp đang tạo Khóa đó chính xác từ JSON.

Tôi có bắt đầu với Mô đun và số mũ không?

BigInteger modulus = new BigInteger(1, Base64.decodeBase64(jsonKey.getN())); 
BigInteger exponent = new BigInteger(1, Base64.decodeBase64(jsonKey.getE())); 
publicKey = KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(modulus, exponent)); 

Tôi bắt đầu với x5c, tạo đối tượng X509Certificate và kéo PublicKey từ đó?

CertificateFactory factory = CertificateFactory.getInstance("X.509"); 
X509Certificate cert = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(jsonKey.getX5c()))); 
publicKey = (RSAPublicKey)cert.getPublicKey(); 

Cả hai phương pháp đều không có kết quả.

Nếu tôi tạo RSAPublicKey từ mô đun và số mũ, tôi có thể in khóa được mã hóa Base64Binary để khớp với thuộc tính x5c không? Có lẽ đó không phải là cách tôi nên xác nhận.

Tôi có thể hiểu sai cách để sử dụng điều này.

Như mọi khi, mọi tài liệu cũng được đánh giá cao.

+3

Tôi không biết tiêu chuẩn, nhưng rõ ràng là các module là "n" và số mũ công khai là "e". x5c trông giống như chứng chỉ x509. EDIT: [Ở đây] (https://tools.ietf.org/html/rfc7517) dường như là thông số kỹ thuật. –

+0

Thực ra nó trông giống như cách tiếp cận thứ hai DOES làm việc, có khả năng vì đó là chuỗi chứng chỉ ĐẦY ĐỦ. Tôi vẫn chưa rõ mối quan hệ giữa e, n và x5c khi nó được trả về từ điểm cuối đó. Tôi thấy các thiết bị đầu cuối khác chỉ bao gồm chuỗi chứng nhận. Không thể tìm thấy tài liệu Microsoft xung quanh các khóa công cộng. –

Trả lời

2

x5c chứa chuỗi chứng nhận. Giấy chứng nhận đầu tiên của chuỗi phải phù hợp với các giá trị quan trọng được đại diện bởi các giá trị khác trong JWK, trong trường hợp này ne, do đó khóa công khai được chiết xuất từ ​​x5c[0] và một trong những xây dựng với ne phải giống hệt nhau

Giá trị JWK được mã hóa trong base64url, không phải trong base64. Thay đổi

BigInteger modulus = new BigInteger(1, Base64.decodeBase64(jsonKey.getN())); 
BigInteger exponent = new BigInteger(1, Base64.decodeBase64(jsonKey.getE())); 

với

BigInteger modulus = new BigInteger(1, Base64.getUrlDecoder().decode(jsonKey.getN())); 
BigInteger exponent = new BigInteger(1, Base64.getUrlDecoder().decode(jsonKey.getE())); 
+0

Điều này giúp ích! Mô-đun và số mũ được cung cấp tương ứng với khóa công khai của chứng chỉ đầu tiên trong chuỗi chứng chỉ. Toàn bộ chuỗi là cần thiết để xác minh chữ ký và không chỉ là mod và exp như ban đầu tôi đã cố gắng. –

Các vấn đề liên quan