We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ECDSA is not supported under Default JWS SignerFactory, or under Default JWS Verifit Factory We can implement a Signer and Verfit
import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSHeader; import com.nimbusds.jose.JWSSigner; import com.nimbusds.jose.crypto.impl.BaseJWSProvider; import com.nimbusds.jose.jwk.Curve; import com.nimbusds.jose.jwk.OctetKeyPair; import com.nimbusds.jose.util.Base64URL; import lombok.SneakyThrows; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.Set; public class EdDSASigner extends BaseJWSProvider implements JWSSigner { private final Signature signature; private final String algorithmName; public static final Set<JWSAlgorithm> SUPPORTED_ALGORITHMS; public static final Set<Curve> SUPPORTED_CURVES; static { SUPPORTED_ALGORITHMS = Set.of(JWSAlgorithm.EdDSA, JWSAlgorithm.Ed25519, JWSAlgorithm.Ed448); SUPPORTED_CURVES = Set.of(Curve.Ed25519, Curve.Ed448); } @SneakyThrows public EdDSASigner(OctetKeyPair keyPair) { super(SUPPORTED_ALGORITHMS); algorithmName = keyPair.getAlgorithm().getName(); signature = Signature.getInstance(algorithmName, "BC"); PrivateKey privateKey = getPrivateKey(keyPair.getD().decode()); signature.initSign(privateKey, new SecureRandom()); } // 从 Base64 编码的字符串转换回 PrivateKey 对象 public PrivateKey getPrivateKey(byte[] bytes) throws Exception { PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes); KeyFactory keyFactory = KeyFactory.getInstance(algorithmName, "BC"); return keyFactory.generatePrivate(keySpec); } @Override @SneakyThrows public Base64URL sign(JWSHeader jwsHeader, byte[] bytes) throws JOSEException { signature.update(bytes); byte[] signatureBytes = signature.sign(); return new Base64URL(Base64.getUrlEncoder().encodeToString(signatureBytes)); } }
import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSHeader; import com.nimbusds.jose.JWSVerifier; import com.nimbusds.jose.crypto.impl.BaseJWSProvider; import com.nimbusds.jose.crypto.impl.CriticalHeaderParamsDeferral; import com.nimbusds.jose.jwk.OctetKeyPair; import com.nimbusds.jose.util.Base64URL; import lombok.SneakyThrows; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.Set; public class EdDSAVerifier extends BaseJWSProvider implements JWSVerifier { public static Set<JWSAlgorithm> SUPPORTED_ALGORITHMS; private Signature signature; private String algorithmName = "EdDSA"; private final CriticalHeaderParamsDeferral critPolicy = new CriticalHeaderParamsDeferral(); static { SUPPORTED_ALGORITHMS = Set.of(JWSAlgorithm.EdDSA, JWSAlgorithm.Ed25519, JWSAlgorithm.Ed448); } @SneakyThrows public EdDSAVerifier(OctetKeyPair keyPair) { super(SUPPORTED_ALGORITHMS); algorithmName = keyPair.getAlgorithm().getName(); signature = Signature.getInstance(algorithmName, "BC"); signature.initVerify(getPublicKey(keyPair)); } private PublicKey getPublicKey(OctetKeyPair keyPair) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException { byte[] decodedX = keyPair.getDecodedX(); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedX); KeyFactory keyFactory = KeyFactory.getInstance(algorithmName, "BC"); return keyFactory.generatePublic(keySpec); } @Override @SneakyThrows public boolean verify(JWSHeader jwsHeader, byte[] bytes, Base64URL base64URL) throws JOSEException { // Check for unrecognized "crit" properties if (! critPolicy.headerPasses(jwsHeader)) { return false; } signature.update(bytes); return signature.verify(base64URL.decode()); } }
import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSSigner; import com.nimbusds.jose.crypto.ECDSASigner; import com.nimbusds.jose.crypto.Ed25519Signer; import com.nimbusds.jose.crypto.MACSigner; import com.nimbusds.jose.crypto.RSASSASigner; import com.nimbusds.jose.jca.JCAContext; import com.nimbusds.jose.jwk.*; import com.nimbusds.jose.produce.JWSSignerFactory; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; public class JWSSignerFactoryImpl implements JWSSignerFactory { /** * The JCA context. */ private final JCAContext jcaContext = new JCAContext(); /** * The supported JWS algorithms. */ public static final Set<JWSAlgorithm> SUPPORTED_ALGORITHMS; static { Set<JWSAlgorithm> algs = new LinkedHashSet<>(); algs.addAll(MACSigner.SUPPORTED_ALGORITHMS); algs.addAll(RSASSASigner.SUPPORTED_ALGORITHMS); algs.addAll(ECDSASigner.SUPPORTED_ALGORITHMS); algs.addAll(EdDSASigner.SUPPORTED_ALGORITHMS); algs.addAll(Ed25519Signer.SUPPORTED_ALGORITHMS); SUPPORTED_ALGORITHMS = Collections.unmodifiableSet(algs); } @Override public Set<JWSAlgorithm> supportedJWSAlgorithms() { return SUPPORTED_ALGORITHMS; } @Override public JCAContext getJCAContext() { return jcaContext; } @Override public JWSSigner createJWSSigner(final JWK key) throws JOSEException { if (!key.isPrivate()) { // can't create a signer without the private key throw JWKException.expectedPrivate(); } if (key.getKeyUse() != null && ! KeyUse.SIGNATURE.equals(key.getKeyUse())) { throw new JWKException("The JWK use must be sig (signature) or unspecified"); } JWSSigner signer; // base this just on the key type (+ curve) alone without the algorithm check if (key instanceof OctetSequenceKey) { signer = new MACSigner((OctetSequenceKey)key); } else if (key instanceof RSAKey) { signer = new RSASSASigner((RSAKey)key); } else if (key instanceof ECKey && ECDSASigner.SUPPORTED_CURVES.contains(((ECKey) key).getCurve())) { signer = new ECDSASigner((ECKey)key); } else if (key instanceof OctetKeyPair && EdDSASigner.SUPPORTED_CURVES.contains(((OctetKeyPair) key).getCurve())) { signer = new EdDSASigner((OctetKeyPair)key); } else if (key instanceof OctetKeyPair && Ed25519Signer.SUPPORTED_CURVES.contains(((OctetKeyPair) key).getCurve())) { signer = new Ed25519Signer((OctetKeyPair)key); } else { throw new JOSEException("Unsupported JWK type and / or curve"); } // Apply JCA context signer.getJCAContext().setSecureRandom(jcaContext.getSecureRandom()); signer.getJCAContext().setProvider(jcaContext.getProvider()); return signer; } @Override public JWSSigner createJWSSigner(final JWK key, final JWSAlgorithm alg) throws JOSEException { if (!key.isPrivate()) { // can't create a signer without the private key throw JWKException.expectedPrivate(); } if (key.getKeyUse() != null && ! KeyUse.SIGNATURE.equals(key.getKeyUse())) { throw new JWKException("The JWK use must be sig (signature) or unspecified"); } JWSSigner signer; if ( MACSigner.SUPPORTED_ALGORITHMS.contains(alg) && key instanceof OctetSequenceKey) { signer = new MACSigner((OctetSequenceKey)key); } else if ( RSASSASigner.SUPPORTED_ALGORITHMS.contains(alg) && key instanceof RSAKey) { signer = new RSASSASigner((RSAKey)key); } else if ( ECDSASigner.SUPPORTED_ALGORITHMS.contains(alg) && key instanceof ECKey && ECDSASigner.SUPPORTED_CURVES.contains(((ECKey) key).getCurve())) { signer = new ECDSASigner((ECKey)key); } else if ( EdDSASigner.SUPPORTED_ALGORITHMS.contains(alg) && key instanceof OctetKeyPair ){ signer = new EdDSASigner((OctetKeyPair)key); } else if ( Ed25519Signer.SUPPORTED_ALGORITHMS.contains(alg) && key instanceof OctetKeyPair && Ed25519Signer.SUPPORTED_CURVES.contains(((OctetKeyPair) key).getCurve())) { signer = new Ed25519Signer((OctetKeyPair)key); } else { throw new JOSEException("Unsupported JWK type, JWK curve and / or JWS algorithm"); } // Apply JCA context signer.getJCAContext().setSecureRandom(jcaContext.getSecureRandom()); signer.getJCAContext().setProvider(jcaContext.getProvider()); return signer; } }
import com.nimbusds.jose.*; import com.nimbusds.jose.crypto.ECDSAVerifier; import com.nimbusds.jose.crypto.MACVerifier; import com.nimbusds.jose.crypto.RSASSAVerifier; import com.nimbusds.jose.jca.JCAContext; import com.nimbusds.jose.jwk.*; import javax.crypto.SecretKey; import java.security.PublicKey; import java.security.interfaces.ECPublicKey; import java.security.interfaces.RSAPublicKey; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; public class JWSVerifierFactoryImpl { /** * The supported JWS algorithms. */ public static final Set<JWSAlgorithm> SUPPORTED_ALGORITHMS; static { Set<JWSAlgorithm> algs = new LinkedHashSet<>(); algs.addAll(MACVerifier.SUPPORTED_ALGORITHMS); algs.addAll(RSASSAVerifier.SUPPORTED_ALGORITHMS); algs.addAll(ECDSAVerifier.SUPPORTED_ALGORITHMS); algs.addAll(EdDSAVerifier.SUPPORTED_ALGORITHMS); SUPPORTED_ALGORITHMS = Collections.unmodifiableSet(algs); } /** * The JCA context. */ private final JCAContext jcaContext = new JCAContext(); public Set<JWSAlgorithm> supportedJWSAlgorithms() { return SUPPORTED_ALGORITHMS; } public JCAContext getJCAContext() { return jcaContext; } public JWSVerifier createJWSVerifier(final JWSHeader header, final JWK key) throws JOSEException { JWSVerifier verifier; if (MACVerifier.SUPPORTED_ALGORITHMS.contains(header.getAlgorithm())) { if (!(key instanceof OctetSequenceKey macKey)) { throw new KeyTypeException(SecretKey.class); } verifier = new MACVerifier(macKey); } else if (RSASSAVerifier.SUPPORTED_ALGORITHMS.contains(header.getAlgorithm())) { if (!(key instanceof RSAKey rsaKey)) { throw new KeyTypeException(RSAPublicKey.class); } verifier = new RSASSAVerifier(rsaKey); } else if (ECDSAVerifier.SUPPORTED_ALGORITHMS.contains(header.getAlgorithm())) { if (!(key instanceof ECKey ecKey)) { throw new KeyTypeException(ECPublicKey.class); } verifier = new ECDSAVerifier(ecKey); } else if (EdDSAVerifier.SUPPORTED_ALGORITHMS.contains(header.getAlgorithm())) { if (!(key instanceof OctetKeyPair keyPair)){ throw new KeyTypeException(PublicKey.class); } verifier = new EdDSAVerifier(keyPair); } else { throw new JOSEException("Unsupported JWS algorithm: " + header.getAlgorithm()); } // Apply JCA context, SecureRandom expensive and not needed for verification (iss #385) verifier.getJCAContext().setProvider(jcaContext.getProvider()); return verifier; } }
example
public class JWTGenerate { static { // 注册 Bouncy Castle 提供者 if (Security.getProvider("BC") == null) { Security.addProvider(new BouncyCastleProvider()); } } @SneakyThrows public static String generate(JWK jwk, JWTClaimsSet claimsSet, String... headers) { Map<String, Object> headersMap = new HashMap<>(); if (headers != null && headers.length > 0) { if (headers.length % 2 != 0) { throw new IllegalArgumentException("headers length must be even"); } for (int i = 0; i < headers.length; i += 2) { headersMap.put(headers[i], headers[i + 1]); } } JWSHeader header = new JWSHeader.Builder(getAlgorithm(jwk)) .base64URLEncodePayload(true) .keyID(jwk.getKeyID()) .customParams(headersMap) .build(); JWSObject jwsObject = new JWSObject(header, claimsSet.toPayload()); JWSSigner signer = new JWSSignerFactoryImpl().createJWSSigner(jwk); jwsObject.sign(signer); return jwsObject.serialize(); } @SneakyThrows public static JWSAlgorithm getAlgorithm(JWK jwk) { Algorithm alg = jwk.getAlgorithm(); if (alg == null) { throw new IllegalArgumentException("JWK does not contain an algorithm"); } return JWSAlgorithm.parse(alg.getName()); } @SneakyThrows public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, JOSEException, InvalidKeySpecException, InvalidKeyException { // 确保提供者已经注册 if (Security.getProvider("BC") == null) { throw new IllegalStateException("Bouncy Castle provider not found"); } KeyPair keyPair = KeyPairGenerator.getInstance("ED448", "BC").generateKeyPair(); JWK jwk = new OctetKeyPair.Builder(Curve.Ed448,new Base64URL(Base64.getUrlEncoder().encodeToString(keyPair.getPublic().getEncoded()))).d(new Base64URL(Base64.getUrlEncoder().encodeToString(keyPair.getPrivate().getEncoded()))).keyID(UUID.randomUUID().toString().toUpperCase()).algorithm(JWSAlgorithm.EdDSA).build(); boolean contains = OctetKeyPair.SUPPORTED_CURVES.contains(Curve.Ed448); System.out.println(contains); // JWK jwk = new OctetKeyPairGenerator(Curve.Ed448).keyID(UUID.randomUUID().toString().toUpperCase()).algorithm(JWSAlgorithm.EdDSA).generate(); String generate = generate(jwk, new JWTClaimsSet.Builder().jwtID(UUID.randomUUID().toString().toUpperCase()).subject("1").audience(List.of("web", "app")).issuer("example.com").expirationTime(new Date(System.currentTimeMillis() + 1000 * 60)).build()); System.out.println(generate); JWSObject jwsObject = JWSObject.parse(generate); JWSVerifier jwtsVerifier = new JWSVerifierFactoryImpl().createJWSVerifier(jwsObject.getHeader(),jwk); boolean verify = jwsObject.verify(jwtsVerifier); System.out.println(verify); } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
ECDSA is not supported under Default JWS SignerFactory, or under Default JWS Verifit Factory
We can implement a Signer and Verfit
example
The text was updated successfully, but these errors were encountered: