Skip to content

Commit d081573

Browse files
committed
feat: Experimental support for RSA keys.
1 parent 3a40f51 commit d081573

File tree

4 files changed

+98
-21
lines changed

4 files changed

+98
-21
lines changed

src/main/java/com/danubetech/keyformats/JWK_to_PrivateKey.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package com.danubetech.keyformats;
22

3+
import java.math.BigInteger;
4+
import java.security.KeyFactory;
35
import java.security.interfaces.RSAPrivateKey;
6+
import java.security.spec.RSAPrivateKeySpec;
47

58
import bbs.signatures.KeyPair;
69
import com.danubetech.keyformats.jose.Curve;
@@ -37,15 +40,28 @@ public static RSAPrivateKey JWK_to_RSAPrivateKey(JWK jsonWebKey) {
3740

3841
if (! KeyType.RSA.equals(jsonWebKey.getKty())) throw new IllegalArgumentException("Incorrect key type: " + jsonWebKey.getKty());
3942

40-
throw new RuntimeException("Not supported");
41-
// return ((RSAKey) jsonWebKey).toRSAPrivateKey();
43+
try {
44+
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
45+
RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(new BigInteger(jsonWebKey.getNdecoded()), new BigInteger(jsonWebKey.getDdecoded()));
46+
return (RSAPrivateKey) keyFactory.generatePrivate(rsaPrivateKeySpec);
47+
} catch (Exception ex) {
48+
throw new RuntimeException(ex.getMessage(), ex);
49+
}
50+
}
51+
52+
public static byte[] JWK_to_RSAPrivateKeyBytes(JWK jsonWebKey) {
53+
54+
if (! KeyType.RSA.equals(jsonWebKey.getKty())) throw new IllegalArgumentException("Incorrect key type: " + jsonWebKey.getKty());
55+
56+
return JWK_to_RSAPrivateKey(jsonWebKey).getEncoded();
4257
}
4358

4459
public static ECKey JWK_to_secp256k1PrivateKey(JWK jsonWebKey) {
4560

46-
byte[] privateKeyBytes = JWK_to_secp256k1PrivateKeyBytes(jsonWebKey);
61+
if (! KeyType.EC.equals(jsonWebKey.getKty())) throw new IllegalArgumentException("Incorrect key type: " + jsonWebKey.getKty());
62+
if (! Curve.secp256k1.equals(jsonWebKey.getCrv())) throw new IllegalArgumentException("Incorrect curve: " + jsonWebKey.getCrv());
4763

48-
return ECKey.fromPrivate(privateKeyBytes);
64+
return ECKey.fromPrivate(jsonWebKey.getDdecoded());
4965
}
5066

5167
public static byte[] JWK_to_secp256k1PrivateKeyBytes(JWK jsonWebKey) {

src/main/java/com/danubetech/keyformats/PrivateKey_to_JWK.java

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package com.danubetech.keyformats;
22

3+
import java.security.KeyFactory;
34
import java.security.interfaces.RSAPrivateKey;
45
import java.security.interfaces.RSAPublicKey;
6+
import java.security.spec.PKCS8EncodedKeySpec;
7+
import java.security.spec.X509EncodedKeySpec;
58
import java.util.Arrays;
69

710
import bbs.signatures.KeyPair;
@@ -16,15 +19,29 @@ public class PrivateKey_to_JWK {
1619

1720
public static JWK RSAPrivateKey_to_JWK(RSAPrivateKey privateKey, RSAPublicKey publicKey, String kid, String use) {
1821

19-
throw new RuntimeException("Not supported");
22+
JWK jsonWebKey = new JWK();
23+
jsonWebKey.setKty(KeyType.RSA);
24+
jsonWebKey.setKid(kid);
25+
jsonWebKey.setUse(use);
26+
jsonWebKey.setN(Base64.encodeBase64URLSafeString(privateKey.getModulus().toByteArray()));
27+
jsonWebKey.setD(Base64.encodeBase64URLSafeString(privateKey.getPrivateExponent().toByteArray()));
28+
jsonWebKey.setE(Base64.encodeBase64URLSafeString(publicKey.getPublicExponent().toByteArray()));
29+
30+
return jsonWebKey;
31+
}
32+
33+
public static JWK RSAPrivateKeyBytes_to_JWK(byte[] privateKeyBytes, byte[] publicKeyBytes, String kid, String use) {
2034

21-
/* com.nimbusds.jose.jwk.RSAKey jsonWebKey = new com.nimbusds.jose.jwk.RSAKey.Builder(publicKey)
22-
.privateKey(privateKey)
23-
.keyID(kid)
24-
.keyUse(use == null ? null : new KeyUse(use))
25-
.build();
35+
RSAPrivateKey privateKey;
36+
RSAPublicKey publicKey;
37+
try {
38+
privateKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
39+
publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
40+
} catch (Exception ex) {
41+
throw new RuntimeException(ex.getMessage(), ex);
42+
}
2643

27-
return jsonWebKey;*/
44+
return RSAPrivateKey_to_JWK(privateKey, publicKey, kid, use);
2845
}
2946

3047
public static JWK secp256k1PrivateKey_to_JWK(ECKey privateKey, String kid, String use) {

src/main/java/com/danubetech/keyformats/PublicKey_to_JWK.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package com.danubetech.keyformats;
22

3+
import java.security.KeyFactory;
4+
import java.security.NoSuchAlgorithmException;
35
import java.security.interfaces.RSAPublicKey;
6+
import java.security.spec.InvalidKeySpecException;
7+
import java.security.spec.X509EncodedKeySpec;
48

59
import bbs.signatures.KeyPair;
610
import com.danubetech.keyformats.jose.Curve;
@@ -14,18 +18,26 @@ public class PublicKey_to_JWK {
1418

1519
public static JWK RSAPublicKey_to_JWK(RSAPublicKey publicKey, String kid, String use) {
1620

17-
throw new RuntimeException("Not supported");
18-
19-
/* JWK jsonWebKey = new JWK();
21+
JWK jsonWebKey = new JWK();
22+
jsonWebKey.setKty(KeyType.RSA);
2023
jsonWebKey.setKid(kid);
2124
jsonWebKey.setUse(use);
25+
jsonWebKey.setN(Base64.encodeBase64URLSafeString(publicKey.getModulus().toByteArray()));
26+
jsonWebKey.setE(Base64.encodeBase64URLSafeString(publicKey.getPublicExponent().toByteArray()));
27+
28+
return jsonWebKey;
29+
}
30+
31+
public static JWK RSAPublicKeyBytes_to_JWK(byte[] publicKeyBytes, String kid, String use) {
2232

23-
JWK jsonWebKey = new com.nimbusds.jose.jwk.RSAKey.Builder(publicKey)
24-
.keyID(kid)
25-
.keyUse(use == null ? null : new KeyUse(use))
26-
.build();
33+
RSAPublicKey publicKey;
34+
try {
35+
publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));
36+
} catch (Exception ex) {
37+
throw new RuntimeException(ex.getMessage(), ex);
38+
}
2739

28-
return jsonWebKey;*/
40+
return RSAPublicKey_to_JWK(publicKey, kid, use);
2941
}
3042

3143
public static JWK secp256k1PublicKey_to_JWK(ECKey publicKey, String kid, String use) {

src/main/java/com/danubetech/keyformats/jose/JWK.java

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public class JWK {
2020
private String x;
2121
private String y;
2222
private String d;
23+
private String n;
24+
private String e;
2325

2426
public JWK() {
2527
}
@@ -147,6 +149,34 @@ public byte[] getDdecoded() {
147149
return d != null ? Base64.decodeBase64(d) : null;
148150
}
149151

152+
public String getN() {
153+
return n;
154+
}
155+
156+
public void setN(String n) {
157+
this.n = n;
158+
}
159+
160+
@JsonIgnore
161+
public byte[] getNdecoded() {
162+
String n = this.getN();
163+
return n != null ? Base64.decodeBase64(n) : null;
164+
}
165+
166+
public String getE() {
167+
return e;
168+
}
169+
170+
public void setE(String e) {
171+
this.e = e;
172+
}
173+
174+
@JsonIgnore
175+
public byte[] getEdecoded() {
176+
String e = this.getE();
177+
return e != null ? Base64.decodeBase64(e) : null;
178+
}
179+
150180
/*
151181
* Object methods
152182
*/
@@ -161,6 +191,8 @@ public String toString() {
161191
", x='" + x + '\'' +
162192
", y='" + y + '\'' +
163193
", d='" + d + '\'' +
194+
", n='" + n + '\'' +
195+
", e='" + e + '\'' +
164196
'}';
165197
}
166198

@@ -169,11 +201,11 @@ public boolean equals(Object o) {
169201
if (this == o) return true;
170202
if (o == null || getClass() != o.getClass()) return false;
171203
JWK jwk = (JWK) o;
172-
return Objects.equals(kid, jwk.kid) && Objects.equals(use, jwk.use) && Objects.equals(kty, jwk.kty) && Objects.equals(crv, jwk.crv) && Objects.equals(x, jwk.x) && Objects.equals(y, jwk.y) && Objects.equals(d, jwk.d);
204+
return Objects.equals(kid, jwk.kid) && Objects.equals(use, jwk.use) && Objects.equals(kty, jwk.kty) && Objects.equals(crv, jwk.crv) && Objects.equals(x, jwk.x) && Objects.equals(y, jwk.y) && Objects.equals(d, jwk.d) && Objects.equals(n, jwk.n) && Objects.equals(e, jwk.e);
173205
}
174206

175207
@Override
176208
public int hashCode() {
177-
return Objects.hash(kid, use, kty, crv, x, y, d);
209+
return Objects.hash(kid, use, kty, crv, x, y, d, n, e);
178210
}
179211
}

0 commit comments

Comments
 (0)