下面列出了java.security.KeyFactory#generatePublic ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Test
public void generatePublicKeyFromJWKs() throws Exception {
String jsonJwk = TokenUtils.readResource("/signer-keyset4k.jwk");
System.out.printf("jwk: %s\n", jsonJwk);
JsonObject jwks = Json.createReader(new StringReader(jsonJwk)).readObject();
JsonArray keys = jwks.getJsonArray("keys");
JsonObject jwk = keys.getJsonObject(0);
String e = jwk.getString("e");
String n = jwk.getString("n");
byte[] ebytes = Base64.getUrlDecoder().decode(e);
BigInteger publicExponent = new BigInteger(1, ebytes);
byte[] nbytes = Base64.getUrlDecoder().decode(n);
BigInteger modulus = new BigInteger(1, nbytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, publicExponent);
PublicKey publicKey = kf.generatePublic(rsaPublicKeySpec);
System.out.printf("publicKey=%s\n", publicKey);
String pem = new String(Base64.getEncoder().encode(publicKey.getEncoded()));
System.out.printf("pem: %s\n", pem);
}
private PublicKey getPublicKeyFromPem(String pem)
throws GeneralSecurityException, IOException {
InputStream stream = new ByteArrayInputStream(
pem.getBytes("UTF-8"));
PEMReader reader = new PEMReader(stream);
byte[] bytes = reader.getDerBytes();
PublicKey pubKey;
if (PEMReader.PUBLIC_X509_MARKER.equals(reader.getBeginMarker())) {
KeySpec keySpec = new X509EncodedKeySpec(bytes);
KeyFactory fac = KeyFactory.getInstance("RSA");
pubKey = fac.generatePublic(keySpec);
} else if (PEMReader.CERTIFICATE_X509_MARKER.equals(reader.getBeginMarker())) {
pubKey = getPublicKeyFromDerCert(bytes);
} else {
throw new IOException("Invalid PEM fileL: Unknown marker for " +
" public key or cert " + reader.getBeginMarker());
}
return pubKey;
}
/**
* Internal method to create a new key with inherited key parameters.
*
* @param keyValueKey key from which to obtain key value
* @param keyParamsKey key from which to obtain key parameters
* @return new public key having value and parameters
* @throws CertPathValidatorException if keys are not appropriate types
* for this operation
*/
static PublicKey makeInheritedParamsKey(PublicKey keyValueKey,
PublicKey keyParamsKey) throws CertPathValidatorException
{
if (!(keyValueKey instanceof DSAPublicKey) ||
!(keyParamsKey instanceof DSAPublicKey))
throw new CertPathValidatorException("Input key is not " +
"appropriate type for " +
"inheriting parameters");
DSAParams params = ((DSAPublicKey)keyParamsKey).getParams();
if (params == null)
throw new CertPathValidatorException("Key parameters missing");
try {
BigInteger y = ((DSAPublicKey)keyValueKey).getY();
KeyFactory kf = KeyFactory.getInstance("DSA");
DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
params.getP(),
params.getQ(),
params.getG());
return kf.generatePublic(ks);
} catch (GeneralSecurityException e) {
throw new CertPathValidatorException("Unable to generate key with" +
" inherited parameters: " +
e.getMessage(), e);
}
}
/**
* Verifies a signature.
*
* @param originalMessage The original message.
* @param signedMessage The signature of the original message.
* @param signingPublicKey The public key corresponding to the private key used to sign the message.
* @return Boolean indicating if the signature is verified.
*/
public boolean verifySignature(
byte[] originalMessage,
byte[] signedMessage,
byte[] signingPublicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(cryptographyProperties.getSignatureAlgorithm(), BouncyCastleProvider.PROVIDER_NAME);
KeySpec keySpec = new X509EncodedKeySpec(new SubjectPublicKeyInfo(signatureAlgorithmId, signingPublicKey).getEncoded());
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(cryptographyProperties.getSignatureAlgorithm(), BouncyCastleProvider.PROVIDER_NAME);
signature.initVerify(pubKey);
signature.update(originalMessage);
return signature.verify(signedMessage);
} catch (NoSuchAlgorithmException | NoSuchProviderException
| IOException | InvalidKeySpecException | InvalidKeyException
| SignatureException e) {
return false;
}
}
/**
* 加载公钥
*
* @param publicPemData
* @param algorithm
* @return
* @throws Exception
*/
public static PublicKey loadPemPublicKey(String publicPemData, String algorithm)
throws Exception {
String publicKeyPEM = publicPemData.replace("-----BEGIN PUBLIC KEY-----", "");
publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");
publicKeyPEM = publicKeyPEM.replace("\n", "");
publicKeyPEM = publicKeyPEM.replace("\r", "");
byte[] decoded = Base64.getDecoder().decode(publicKeyPEM.getBytes());
X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded);
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
return keyFactory.generatePublic(spec);
}
/**
* 用公钥加密
*
* @param data
* 待加密数据
* @param key
* 公钥
*
* @return byte[] 加密数据
*
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
// 加入BouncyCastleProvider支持
Security.addProvider(new BouncyCastleProvider());
// 公钥材料转换
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
// 实例化密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 生成公钥
Key publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
static ECDHECredentials valueOf(NamedGroup namedGroup,
byte[] encodedPoint) throws IOException, GeneralSecurityException {
if (namedGroup.spec != NamedGroupSpec.NAMED_GROUP_ECDHE) {
throw new RuntimeException(
"Credentials decoding: Not ECDHE named group");
}
if (encodedPoint == null || encodedPoint.length == 0) {
return null;
}
ECParameterSpec parameters =
(ECParameterSpec)namedGroup.keAlgParamSpec;
ECPoint point = ECUtil.decodePoint(
encodedPoint, parameters.getCurve());
KeyFactory factory = KeyFactory.getInstance("EC");
ECPublicKey publicKey = (ECPublicKey)factory.generatePublic(
new ECPublicKeySpec(point, parameters));
return new ECDHECredentials(publicKey, namedGroup);
}
private RSAPublicKey loadPublicKey() {
String publicPEM = Config.cveAttackModePublicKey.replaceAll("\\n", "").replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "");
;
KeyFactory kf;
try {
kf = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(Base64.getDecoder().decode(publicPEM));
return (RSAPublicKey) kf.generatePublic(keySpecX509);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static PublicKey getECPublicKey(ECPoint ecPoint, ECParameterSpec curveSpec, Provider provider) {
// Create public key spec with given point
try {
ECPublicKeySpec pubSpec = new ECPublicKeySpec(ecPoint, curveSpec);
KeyFactory kf = provider != null ? KeyFactory.getInstance("EC", provider)
: KeyFactory.getInstance("EC", "SunEC");
return (ECPublicKey) kf.generatePublic(pubSpec);
} catch (GeneralSecurityException e) {
throw new IllegalStateException(e);
}
}
/**
* 根据模数和公钥指数生成公钥
*
* @param modulus
* @param publicExponent
* @return 公钥
*/
public static PublicKey generateRSAPublicKey(String modulus,
String publicExponent) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(
modulus), new BigInteger(publicExponent));
return keyFactory.generatePublic(pubKeySpec);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 数字签名校验
*
* @param data 二进位组
* @param publicKey 公钥(BASE64编码)
* @param sign 数字签名字符串
* @return true:校验成功,false:校验失败
* @throws Exception 异常
*/
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
byte[] keyBytes = Base64.decode(publicKey.getBytes(), Base64.DEFAULT);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = getKeyFactory();
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64.decode(sign.getBytes(), Base64.DEFAULT));
}
private void init(BigInteger mod, BigInteger exp) {
try {
final RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(mod, exp);
final KeyFactory factory = KeyFactory.getInstance("RSA");
RSAPublicKey rsaKey = (RSAPublicKey) factory.generatePublic(publicKeySpec);
cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", CryptoHelper.SEC_PROV);
cipher.init(Cipher.ENCRYPT_MODE, rsaKey);
} catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidKeySpecException
| NoSuchProviderException e) {
logger.debug(e);
}
}
/**
* 得到公钥
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = new Base64Encoder().decode(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
public static ECPublicKey getECPublicKey(String curve, byte[] xPoint, byte[] yPoint) {
try {
ECParameterSpec params = getECParameterSpec(curve, false);
ECPoint ecPoint = new ECPoint(toBigInteger(xPoint),
toBigInteger(yPoint));
ECPublicKeySpec keySpec = new ECPublicKeySpec(ecPoint, params);
KeyFactory kf = KeyFactory.getInstance("EC");
return (ECPublicKey) kf.generatePublic(keySpec);
} catch (Exception ex) {
throw new SecurityException(ex);
}
}
public static PublicKey getPublicKey(String filename) throws Exception {
byte[] keyBytes = Files.readAllBytes(Paths.get(filename));
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
private PublicKey createRSAPublicKey() {
BigInteger modulus = new BigInteger(1, Base64Url.decode(jwk.getOtherClaims().get(RSAPublicJWK.MODULUS).toString()));
BigInteger publicExponent = new BigInteger(1, Base64Url.decode(jwk.getOtherClaims().get(RSAPublicJWK.PUBLIC_EXPONENT).toString()));
try {
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(new RSAPublicKeySpec(modulus, publicExponent));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* <p>
* 校验数字签名
* </p>
* @param data 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param sign 数字签名
* @return
* @throws Exception
*/
public static boolean verify(byte[] data, byte[] publicKey, byte[] sign) throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64Utils.decode(sign));
}
/**
* You can component a publicKey by a specific pair of values - modulus and
* exponent.
*
* @param modulus When you generate a new RSA KeyPair, you'd get a PrivateKey, a
* modulus and an exponent.
* @param exponent When you generate a new RSA KeyPair, you'd get a PrivateKey, a
* modulus and an exponent.
* @throws ClassNotFoundException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
private Key convertStringToPublicKey(BigInteger modulus, BigInteger exponent)
throws ClassNotFoundException, NoSuchAlgorithmException, InvalidKeySpecException {
byte[] modulusByteArry = modulus.toByteArray();
byte[] exponentByteArry = exponent.toByteArray();
// 由接收到的参数构造RSAPublicKeySpec对象
RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(new BigInteger(modulusByteArry),
new BigInteger(exponentByteArry));
// 根据RSAPublicKeySpec对象获取公钥对象
KeyFactory kFactory = KeyFactory.getInstance(Algorithm.KEYPAIR_ALGORITHM);
PublicKey publicKey = kFactory.generatePublic(rsaPublicKeySpec);
return publicKey;
}
@Override
public void consume(ConnectionContext context,
ByteBuffer message) throws IOException {
// The consuming happens in server side only.
ServerHandshakeContext shc = (ServerHandshakeContext)context;
X509Possession x509Possession = null;
for (SSLPossession possession : shc.handshakePossessions) {
if (possession instanceof X509Possession) {
x509Possession = (X509Possession)possession;
break;
}
}
if (x509Possession == null) {
// unlikely, have been checked during cipher suite negotiation.
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
"No expected EC server cert for ECDH client key exchange");
}
ECParameterSpec params = x509Possession.getECParameterSpec();
if (params == null) {
// unlikely, have been checked during cipher suite negotiation.
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
"Not EC server cert for ECDH client key exchange");
}
NamedGroup namedGroup = NamedGroup.valueOf(params);
if (namedGroup == null) {
// unlikely, have been checked during cipher suite negotiation.
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
"Unsupported EC server cert for ECDH client key exchange");
}
SSLKeyExchange ke = SSLKeyExchange.valueOf(
shc.negotiatedCipherSuite.keyExchange,
shc.negotiatedProtocol);
if (ke == null) {
// unlikely
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
"Not supported key exchange type");
}
// parse the handshake message
ECDHClientKeyExchangeMessage cke =
new ECDHClientKeyExchangeMessage(shc, message);
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.fine(
"Consuming ECDH ClientKeyExchange handshake message", cke);
}
// create the credentials
try {
ECPoint point =
JsseJce.decodePoint(cke.encodedPoint, params.getCurve());
ECPublicKeySpec spec = new ECPublicKeySpec(point, params);
KeyFactory kf = JsseJce.getKeyFactory("EC");
ECPublicKey peerPublicKey =
(ECPublicKey)kf.generatePublic(spec);
// check constraints of peer ECPublicKey
if (!shc.algorithmConstraints.permits(
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
peerPublicKey)) {
throw new SSLHandshakeException(
"ECPublicKey does not comply to algorithm constraints");
}
shc.handshakeCredentials.add(new ECDHECredentials(
peerPublicKey, namedGroup));
} catch (GeneralSecurityException | java.io.IOException e) {
throw (SSLHandshakeException)(new SSLHandshakeException(
"Could not generate ECPublicKey").initCause(e));
}
// update the states
SSLKeyDerivation masterKD = ke.createKeyDerivation(shc);
SecretKey masterSecret =
masterKD.deriveKey("MasterSecret", null);
shc.handshakeSession.setMasterSecret(masterSecret);
SSLTrafficKeyDerivation kd =
SSLTrafficKeyDerivation.valueOf(shc.negotiatedProtocol);
if (kd == null) {
// unlikely
throw shc.conContext.fatal(Alert.INTERNAL_ERROR,
"Not supported key derivation: " + shc.negotiatedProtocol);
} else {
shc.handshakeKeyDerivation =
kd.createKeyDerivation(shc, masterSecret);
}
}
protected void
completeDH(
byte[] buffer )
throws IOException
{
try{
BigInteger other_dh_y = bytesToBigInteger( buffer, 0, DH_SIZE_BYTES );
KeyFactory dh_key_factory = KeyFactory.getInstance("DH");
PublicKey other_public_key = dh_key_factory.generatePublic( new DHPublicKeySpec( other_dh_y, DH_P_BI, DH_G_BI ));
key_agreement.doPhase( other_public_key, true );
secret_bytes = key_agreement.generateSecret();
adapter.gotSecret( secret_bytes );
// System.out.println( "secret = " + ByteFormatter.encodeString( secret_bytes ));
}catch( Throwable e ){
throw( new IOException( Debug.getNestedExceptionMessage(e)));
}
}