質問編集履歴
10
修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-18/0007e21f-8c06-4158-baeb-123b08ee1c18.png)
|
19
19
|
|
20
20
|
### 発生している問題・エラーメッセージ
|
21
|
-
|
21
|
+
プログラム自体は正常に動いてJWTが生成されるのですが、Postmanを用いてLINEWORKS APIを実行しようとするとエラーが発生してしまいます。
|
22
22
|
そのため、以下の2点を質問させてください。
|
23
23
|
|
24
24
|
①string型の秘密鍵を RSAPrivateKey型に変える方法は「該当のソースコード」項目に記載してあるような方法で合っているか?
|
9
修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
そのため、以下の2点を質問させてください。
|
23
23
|
|
24
24
|
①string型の秘密鍵を RSAPrivateKey型に変える方法は「該当のソースコード」項目に記載してあるような方法で合っているか?
|
25
|
+
[https://stackoverflow.com/questions/34454531/java-how-can-i-generate-privatekey-from-a-string ](https://stackoverflow.com/questions/34454531/java-how-can-i-generate-privatekey-from-a-string)を参考に作成しました。
|
25
26
|
|
26
27
|
|
27
28
|
②[こちらのページ](https://developers.worksmobile.com/jp/reference/authorization-sa?lang=ja)のようなJWT署名をやりたい場合、 **秘密鍵を用いたJWT生成は以下のコードで合っているか?**
|
8
syuusei
test
CHANGED
File without changes
|
test
CHANGED
@@ -40,7 +40,7 @@
|
|
40
40
|
|
41
41
|
```Java
|
42
42
|
//秘密鍵の設定
|
43
|
-
String privateKey = {改行
|
43
|
+
String privateKey = {"-----BEGIN PRIVATE KEY-----" と改行、"-----END PRIVATE KEY-----" を除去した秘密鍵};
|
44
44
|
|
45
45
|
//ヘッダーの設定
|
46
46
|
Map<String, Object> headerClaims = new HashMap();
|
7
syuusei
test
CHANGED
File without changes
|
test
CHANGED
@@ -53,6 +53,7 @@
|
|
53
53
|
payloadClaims.put("iat", "JWT生成日時");
|
54
54
|
payloadClaims.put("exp", "JWT満了日時");
|
55
55
|
|
56
|
+
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
56
57
|
byte[] keyContentAsBytes = Base64.getDecoder().decode(privateKey);
|
57
58
|
PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(keyContentAsBytes)
|
58
59
|
//RSA256を用いた電子署名
|
6
しゅうせい
test
CHANGED
File without changes
|
test
CHANGED
@@ -58,7 +58,7 @@
|
|
58
58
|
//RSA256を用いた電子署名
|
59
59
|
try {
|
60
60
|
RSAPrivateKey privKey = (RSAPrivateKey)keyFactory.generatePrivate(privSpec);
|
61
|
-
Algorithm algorithm = Algorithm.RSA256(null, priv
|
61
|
+
Algorithm algorithm = Algorithm.RSA256(null, privKey);
|
62
62
|
String token = JWT.create()
|
63
63
|
.withHeader(headerClaims)
|
64
64
|
.withPayload(payloadClaims)
|
5
追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -18,25 +18,17 @@
|
|
18
18
|
![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-18/0007e21f-8c06-4158-baeb-123b08ee1c18.png)
|
19
19
|
|
20
20
|
### 発生している問題・エラーメッセージ
|
21
|
-
java-jwt では、RSA256アルゴリズムで暗号化するためにはRSAPrivateKey型の秘密鍵を指定する必要があるのですが、秘密鍵を**String型の状態からどのようにしてRSAPrivateKey型に変換するかが分からない**状態です。また、
|
21
|
+
java-jwt では、RSA256アルゴリズムで暗号化するためにはRSAPrivateKey型の秘密鍵を指定する必要があるのですが、秘密鍵を**String型の状態からどのようにしてRSAPrivateKey型に変換するかが分からない**状態です。また、参考例だけではどのようにRS256による電子署名を行うのかが具体的に理解することができませんでした。
|
22
|
+
そのため、以下の2点を質問させてください。
|
22
23
|
|
23
|
-
①string型の秘密鍵を RSAPrivateKey型に変える
|
24
|
+
①string型の秘密鍵を RSAPrivateKey型に変える方法は「該当のソースコード」項目に記載してあるような方法で合っているか?
|
24
|
-
②[こちらのページ](https://developers.worksmobile.com/jp/reference/authorization-sa?lang=ja)の ヘッダーやペイロード情報を付与させるには以下のような記述で合っているか?
|
25
|
-
```Java
|
26
|
-
Map<String, Object> headerClaims = new HashMap();
|
27
|
-
//ヘッダーのalg と typ は自動で付与されるため何も書かない
|
28
25
|
|
29
|
-
Map<String, Object> payloadClaims = new HashMap<>();
|
30
|
-
payloadClaims.put("iss", "Client ID");
|
31
|
-
payloadClaims.put("sub", "Service Account");
|
32
|
-
payloadClaims.put("iat", "JWT生成日時");
|
33
|
-
payloadClaims.put("exp", "JWT満了日時");
|
34
26
|
|
27
|
+
②[こちらのページ](https://developers.worksmobile.com/jp/reference/authorization-sa?lang=ja)のようなJWT署名をやりたい場合、 **秘密鍵を用いたJWT生成は以下のコードで合っているか?**
|
28
|
+
(最終的なJWTとして、一応それっぽいものは生成されるのですが、Postmanを用いて確認すると「500 Internal Server Error」となり、正しいJWTではないことが予想されます)
|
29
|
+
|
35
|
-
S
|
30
|
+
一応、ヘッダーとペイロード情報は正常にBASE64エンコードできたことは確認済みです。
|
36
|
-
|
31
|
+
|
37
|
-
.withPayload(payloadClaims)
|
38
|
-
.sign(algorithm);
|
39
|
-
```
|
40
32
|
|
41
33
|
### 該当のソースコード
|
42
34
|
gradleへのインポート
|
@@ -48,12 +40,7 @@
|
|
48
40
|
|
49
41
|
```Java
|
50
42
|
//秘密鍵の設定
|
51
|
-
String privateKey
|
43
|
+
String privateKey = {改行等を除去した秘密鍵};
|
52
|
-
"wzLaxWoh... //中略 \n" +
|
53
|
-
"-----END PRIVATE KEY-----";
|
54
|
-
|
55
|
-
privateKey_string = //{privateKey_string} から改行や "-----BEGIN PRIVATE KEY-----" を適切に除去する ;
|
56
|
-
RSAPrivateKey privateKey = //privateKey_string を RSAPrivateKey型に変換したい
|
57
44
|
|
58
45
|
//ヘッダーの設定
|
59
46
|
Map<String, Object> headerClaims = new HashMap();
|
@@ -66,17 +53,27 @@
|
|
66
53
|
payloadClaims.put("iat", "JWT生成日時");
|
67
54
|
payloadClaims.put("exp", "JWT満了日時");
|
68
55
|
|
56
|
+
byte[] keyContentAsBytes = Base64.getDecoder().decode(privateKey);
|
57
|
+
PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(keyContentAsBytes)
|
69
58
|
//RSA256を用いた電子署名
|
70
59
|
try {
|
60
|
+
RSAPrivateKey privKey = (RSAPrivateKey)keyFactory.generatePrivate(privSpec);
|
71
61
|
Algorithm algorithm = Algorithm.RSA256(null, privateKey);
|
72
62
|
String token = JWT.create()
|
73
63
|
.withHeader(headerClaims)
|
74
64
|
.withPayload(payloadClaims)
|
75
65
|
.sign(algorithm);
|
66
|
+
System.out.println("JWT = " + token );
|
76
67
|
} catch (JWTCreationException exception){
|
77
68
|
//Invalid Signing configuration / Couldn't convert Claims.
|
78
69
|
}
|
79
70
|
```
|
71
|
+
実行結果は以下のようになってしまいます。
|
72
|
+
・JWT自体はエラーが起きずに生成される
|
73
|
+
![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-18/c84fd76b-5bd9-4154-8785-8d008bed11b5.png)
|
74
|
+
|
75
|
+
・200 OK が表示されない
|
76
|
+
![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-18/2c985f17-299c-4fae-8559-bb33fedb3d25.png)
|
80
77
|
申し訳ありませんがどなたかご教授お願い致します。
|
81
78
|
|
82
79
|
### 試したこと
|
4
追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -87,6 +87,7 @@
|
|
87
87
|
```
|
88
88
|
### 追記
|
89
89
|
[こちらのサイト](https://tutorialmore.com/questions-2800307.htm)を参考に、以下のコードをJavaで実行すると正常に動作はするのですが、Postmanを使ってアクセストークンを取得しようとすると「500 Internal Sever Error」と表示されてしまいます。おそらく正しいJWTが取得できていないものだと思われます。
|
90
|
+
本来の質問とはズレてしまうのですが、以下のコードでJWTを取得するためにはどこが間違っているのでしょうか?
|
90
91
|
以下、使用コードです。
|
91
92
|
```Java
|
92
93
|
import java.math.BigInteger;
|
3
追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
JavaでRS256アルゴリズムによるJWT電子署名を生成したいと考えています。
|
4
4
|
現在、[java-jwt](https://github.com/auth0/java-jwt) を用いて実装しようとしています。
|
5
|
+
|
6
|
+
手元には、
|
7
|
+
・BASE64エンコードされたヘッダー情報
|
8
|
+
・BASE64エンコードされたペイロード情報
|
9
|
+
・JWT署名のために必要な秘密鍵
|
10
|
+
がすでに存在するという前提です。
|
5
11
|
|
6
12
|
### 前提
|
7
13
|
|
2
ttuiki
test
CHANGED
File without changes
|
test
CHANGED
@@ -79,7 +79,7 @@
|
|
79
79
|
```
|
80
80
|
echo -n '{BASE64エンコードされたヘッダー}.{BASE64エンコードされたペイロード}' | openssl dgst -sha256 -sign privateKey.key -binary | base64
|
81
81
|
```
|
82
|
-
###追記
|
82
|
+
### 追記
|
83
83
|
[こちらのサイト](https://tutorialmore.com/questions-2800307.htm)を参考に、以下のコードをJavaで実行すると正常に動作はするのですが、Postmanを使ってアクセストークンを取得しようとすると「500 Internal Sever Error」と表示されてしまいます。おそらく正しいJWTが取得できていないものだと思われます。
|
84
84
|
以下、使用コードです。
|
85
85
|
```Java
|
@@ -137,6 +137,8 @@
|
|
137
137
|
}
|
138
138
|
}
|
139
139
|
```
|
140
|
+
実行結果
|
141
|
+
![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-18/6a6fea43-1f36-428c-b557-96b41d0bef0e.png)
|
140
142
|
|
141
143
|
Postmanによる取得結果
|
142
144
|
![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-18/be2899bc-0c12-49fe-b812-606cab3c8a11.png)
|
1
追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -79,6 +79,65 @@
|
|
79
79
|
```
|
80
80
|
echo -n '{BASE64エンコードされたヘッダー}.{BASE64エンコードされたペイロード}' | openssl dgst -sha256 -sign privateKey.key -binary | base64
|
81
81
|
```
|
82
|
+
###追記
|
83
|
+
[こちらのサイト](https://tutorialmore.com/questions-2800307.htm)を参考に、以下のコードをJavaで実行すると正常に動作はするのですが、Postmanを使ってアクセストークンを取得しようとすると「500 Internal Sever Error」と表示されてしまいます。おそらく正しいJWTが取得できていないものだと思われます。
|
84
|
+
以下、使用コードです。
|
85
|
+
```Java
|
86
|
+
import java.math.BigInteger;
|
87
|
+
import java.util.Base64;
|
88
|
+
import java.security.KeyFactory;
|
89
|
+
import java.security.Signature;
|
90
|
+
import java.security.PrivateKey;
|
91
|
+
import java.security.SignatureException;
|
92
|
+
import java.security.NoSuchAlgorithmException;
|
93
|
+
import java.security.spec.RSAPrivateCrtKeySpec;
|
82
94
|
|
95
|
+
import java.security.InvalidKeyException;
|
96
|
+
import java.security.KeyFactory;
|
97
|
+
import java.security.NoSuchAlgorithmException;
|
98
|
+
import java.security.Signature;
|
99
|
+
import java.security.SignatureException;
|
100
|
+
import java.security.interfaces.RSAPrivateKey;
|
101
|
+
import java.security.spec.InvalidKeySpecException;
|
102
|
+
import java.security.spec.PKCS8EncodedKeySpec;
|
103
|
+
|
104
|
+
public class SHA256withRSA {
|
105
|
+
/**
|
106
|
+
* RSASSA-PKCS1-v1_5 with SHA-256によるデジタル署名の生成
|
107
|
+
*/
|
108
|
+
public static void main(String args[]) throws Exception{
|
83
109
|
|
110
|
+
String header_local = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}";
|
111
|
+
String payload_local = "{\"iss\":\"{クライアントID}\",\"sub\":\"{サービスアカウントID}\",\"iat\":1652875817,\"exp\":1652878217}";
|
84
112
|
|
113
|
+
String headerEncoded = Base64.getEncoder().encodeToString(header_local.getBytes());
|
114
|
+
String payloadEncoded = Base64.getEncoder().encodeToString(payload_local.getBytes());
|
115
|
+
|
116
|
+
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
117
|
+
byte[] keyContentAsBytes = Base64.getDecoder().decode("{改行等を除去した秘密鍵本体}");
|
118
|
+
PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(keyContentAsBytes);
|
119
|
+
|
120
|
+
String tempAccessToken = headerEncoded+"."+ payloadEncoded;
|
121
|
+
try {
|
122
|
+
RSAPrivateKey privKey = (RSAPrivateKey)keyFactory.generatePrivate(privSpec);
|
123
|
+
Signature sign = Signature.getInstance("SHA256withRSA");
|
124
|
+
sign.initSign(privKey);
|
125
|
+
sign.update(tempAccessToken.getBytes());
|
126
|
+
byte[] signatureBytes = sign.sign();
|
127
|
+
String jsonToken = Base64.getUrlEncoder().encodeToString(signatureBytes);
|
128
|
+
String JWTtoken = tempAccessToken + "." + jsonToken;
|
129
|
+
System.out.println("JWT = " + JWTtoken);;
|
130
|
+
} catch (InvalidKeySpecException e) {
|
131
|
+
// TODO Auto-generated catch block
|
132
|
+
e.printStackTrace();
|
133
|
+
} catch (SignatureException e) {
|
134
|
+
// TODO Auto-generated catch block
|
135
|
+
e.printStackTrace();
|
136
|
+
}
|
137
|
+
}
|
138
|
+
}
|
139
|
+
```
|
140
|
+
|
141
|
+
Postmanによる取得結果
|
142
|
+
![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-18/be2899bc-0c12-49fe-b812-606cab3c8a11.png)
|
143
|
+
|