🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
公開鍵認証

公開鍵認証とは、公開鍵と秘密鍵の2つの鍵の組を利用する、SSHで利用される認証方式です。

JWT(JSON Web Token)

JWT(JSON Web Token)とは、JSONをベースとしたアクセストークンの仕様。電子署名付きのURL safeなJSONのことを指します。電子署名が付いているため、改ざんをチェックできる点がメリットです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

2109閲覧

jsonからRSAPublicKeyのインスタンスを生成する方法

ios-develper

総合スコア9

公開鍵認証

公開鍵認証とは、公開鍵と秘密鍵の2つの鍵の組を利用する、SSHで利用される認証方式です。

JWT(JSON Web Token)

JWT(JSON Web Token)とは、JSONをベースとしたアクセストークンの仕様。電子署名付きのURL safeなJSONのことを指します。電子署名が付いているため、改ざんをチェックできる点がメリットです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2019/10/29 06:10

現在、Sign in with Apple の実装を行っています。
サーバサイドは、Javaを使用しています。

その中で、Appleが返却してきたJWTを、
https://appleid.apple.com/auth/keys
の、公開鍵で検証してやる必要があるのですが、
https://appleid.apple.com/auth/keys
のjsonから、どうやって、
java.security.interfaces.RSAPublicKey
のインスタンスを生成して良いか分かりません。

どなたか教えて頂けないでしょうか?

jwtのライブラリは、

https://github.com/auth0/java-jwt

を利用しようとしています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

解決しました。

同じ問題で躓いている人のために、
動作検証済みのコードを載せておきます。

ライブラリは
https://github.com/auth0/java-jwt
と、その依存ライブラリおよび
https://github.com/stleary/JSON-java
を入れました。

java

1package jp.sample; 2 3import java.io.BufferedReader; 4import java.io.IOException; 5import java.io.InputStream; 6import java.io.InputStreamReader; 7import java.math.BigInteger; 8import java.net.HttpURLConnection; 9import java.net.URL; 10import java.security.KeyFactory; 11import java.security.NoSuchAlgorithmException; 12import java.security.interfaces.RSAPublicKey; 13import java.security.spec.InvalidKeySpecException; 14import java.security.spec.RSAPublicKeySpec; 15import java.util.Base64; 16 17import org.json.JSONArray; 18import org.json.JSONObject; 19 20import com.auth0.jwt.JWT; 21import com.auth0.jwt.algorithms.Algorithm; 22import com.auth0.jwt.exceptions.JWTVerificationException; 23import com.auth0.jwt.interfaces.JWTVerifier; 24 25public class Sample01JwtVerify { 26 27 /** 28 * 29 * SIWAのJWT検証サンプル 30 * 31 */ 32 public void test() { 33 34 // テスト対象のトークン 35 // ここに、iOSの ASAuthorizationAppleIDCredentialのインスタンスの 36 // 「identityToken」をutf8として解釈した文字列を入れる。 37 String token ="ヘッダー.ペイロード.署名"; 38 39 //---------------------------------------------------------- 40 // ■STEP1 41 // Appleサーバより公開鍵を取得 42 //---------------------------------------------------------- 43 // Appleの公開鍵のURL 44 String strUrl = "https://appleid.apple.com/auth/keys"; 45 46 HttpURLConnection urlConn = null; 47 InputStream in = null; 48 BufferedReader reader = null; 49 String jsonString = null; 50 51 try { 52 53 URL url = new URL(strUrl); 54 urlConn = (HttpURLConnection) url.openConnection(); 55 urlConn.setRequestMethod("GET"); 56 urlConn.connect(); 57 int status = urlConn.getResponseCode(); 58 System.out.println("HTTPステータス:" + status); 59 60 if (status == HttpURLConnection.HTTP_OK) { 61 62 in = urlConn.getInputStream(); 63 reader = new BufferedReader(new InputStreamReader(in)); 64 StringBuilder output = new StringBuilder(); 65 String line; 66 67 while ((line = reader.readLine()) != null) { 68 output.append(line); 69 } 70 71 jsonString = output.toString(); 72 System.out.println("jsonString=" + jsonString); 73 } 74 } catch (IOException e) { 75 e.printStackTrace(); 76 } finally { 77 try { 78 if (reader != null) { 79 reader.close(); 80 } 81 if (urlConn != null) { 82 urlConn.disconnect(); 83 } 84 } catch (IOException e) { 85 e.printStackTrace(); 86 } 87 } 88 // JSON解析 89 JSONObject jsonRoot = new JSONObject(jsonString); 90 91 // keys 92 JSONArray array = jsonRoot.getJSONArray("keys"); 93 94 // key 95 JSONObject key = array.getJSONObject(0); 96 97 // n 98 String n = key.getString("n"); 99 System.out.println("n=" + n); 100 101 // e 102 String e = key.getString("e"); 103 System.out.println("e=" + e); 104 105 //---------------------------------------------------------- 106 // ■STEP2 107 // n(modulus)と、e(publicExponent)を、Base64UrlSafeでデコード 108 //---------------------------------------------------------- 109 Base64.Decoder decorder = Base64.getUrlDecoder(); 110 byte[] modulusBytes = decorder.decode(n); 111 byte[] publicExponentBytes = decorder.decode(e); 112 113 //---------------------------------------------------------- 114 // ■STEP3 115 // 4ビットずつ16進表記に変換 116 //---------------------------------------------------------- 117 String modulusHex = bytesToHex2(modulusBytes); 118 String publicExponentHex = bytesToHex2(publicExponentBytes); 119 System.out.println("modulusHex=" + modulusHex); 120 System.out.println("publicExponentHex=" + publicExponentHex); 121 122 //---------------------------------------------------------- 123 // ■STEP4 124 // BigInteger化する。 125 //---------------------------------------------------------- 126 BigInteger modulesBigInt = new BigInteger(modulusHex, 16); 127 BigInteger exponentBigInt = new BigInteger(publicExponentHex, 16); 128 129 //---------------------------------------------------------- 130 // ■STEP5 131 // RSAPublicKeySpec化する。 132 //---------------------------------------------------------- 133 RSAPublicKeySpec rsaPubKS = new RSAPublicKeySpec(modulesBigInt , exponentBigInt); 134 135 //---------------------------------------------------------- 136 // ■STEP6 137 // RSAPublicKey化する。 138 //---------------------------------------------------------- 139 KeyFactory kf = null; 140 RSAPublicKey publicKey = null; 141 try { 142 kf = KeyFactory.getInstance("RSA"); 143 publicKey = (RSAPublicKey) kf.generatePublic(rsaPubKS); 144 145 } catch (NoSuchAlgorithmException e1) { 146 e1.printStackTrace(); 147 } catch (InvalidKeySpecException e2) { 148 e2.printStackTrace(); 149 } 150 //---------------------------------------------------------- 151 // ■STEP7 152 // 認証する。 153 //---------------------------------------------------------- 154 try { 155 Algorithm algorithm = Algorithm.RSA256(publicKey, null); 156 JWTVerifier verifier = JWT.require(algorithm) 157 .withIssuer("https://appleid.apple.com") 158 .build(); 159 160 verifier.verify(token); 161 162 } catch (JWTVerificationException e3){ 163 164 System.out.println("認証NG"); 165 166 } catch (Exception e4) { 167 e4.printStackTrace(); 168 } 169 System.out.println("認証OK"); 170 } 171 /** 172 * 173 * byte配列を16進数の文字列に変換 174 * 175 * @param hashInBytes 176 * @return 177 */ 178 private String bytesToHex2(byte[] hashInBytes) { 179 180 StringBuilder sb = new StringBuilder(); 181 for (int i = 0; i < hashInBytes.length; i++) { 182 String hex = Integer.toHexString(0xff & hashInBytes[i]); 183 if (hex.length() == 1) sb.append('0'); 184 sb.append(hex); 185 } 186 return sb.toString(); 187 } 188 189} 190

投稿2019/10/29 10:31

ios-develper

総合スコア9

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

同じ箇所で引っかかっていたのでとても助かりました
ありがとうございました!

投稿2022/05/13 08:24

_ayumi_

総合スコア4

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問