package com.kryptnostic.kodex.v1.crypto.keys; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.interfaces.RSAPrivateCrtKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import com.kryptnostic.kodex.v1.crypto.signatures.SignatureAlgorithm; import com.kryptnostic.kodex.v1.crypto.signatures.Signatures; public final class Keys { private Keys() {} public static final KeyPair generateRsaKeyPair( int keySize ) throws NoSuchAlgorithmException { return generateKeyPair( PublicKeyAlgorithm.RSA, keySize ); } public static final KeyPair generateEccKeyPair( int keySize ) throws NoSuchAlgorithmException { return generateKeyPair( PublicKeyAlgorithm.EC, keySize ); } public static final KeyPair generateKeyPair( PublicKeyAlgorithm algorithm, int keySize ) throws NoSuchAlgorithmException { KeyPairGenerator keyGen = KeyPairGenerator.getInstance( algorithm.getValue() ); keyGen.initialize( keySize, new SecureRandom() ); return keyGen.generateKeyPair(); } public static byte[] sign( PrivateKey privateKey, SignatureAlgorithm algorithm, byte[]... data ) throws SignatureException, InvalidKeyException { Signature signer = Signatures.createSigner( algorithm ); signer.initSign( privateKey ); for ( byte[] datum : data ) { signer.update( datum ); } return signer.sign(); } public static boolean verify( PublicKey publicKey, SignatureAlgorithm algorithm, byte[] signature, byte[]... data ) throws SignatureException, InvalidKeyException { Signature signer = Signatures.createSigner( algorithm ); signer.initVerify( publicKey ); for ( byte[] datum : data ) { signer.update( datum ); } return signer.verify( signature ); } public static PublicKey publicKeyFromPrivateKey( PrivateKey privateKey ) throws InvalidKeySpecException, NoSuchAlgorithmException { String algorithm = privateKey.getAlgorithm(); KeyFactory factory = KeyFactory.getInstance( algorithm ); if ( algorithm.equals( PublicKeyAlgorithm.RSA.getValue() ) ) { RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) privateKey; RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec( rsaPrivateKey.getModulus(), rsaPrivateKey.getPublicExponent() ); return factory.generatePublic( publicKeySpec ); } return null; } public static PrivateKey privateKeyFromBytes( PublicKeyAlgorithm algorithm, byte[] bytes ) throws InvalidKeySpecException, NoSuchAlgorithmException { return KeyFactory.getInstance( algorithm.getValue() ).generatePrivate( new PKCS8EncodedKeySpec( bytes ) ); } public static PublicKey publicKeyFromBytes( PublicKeyAlgorithm algorithm, byte[] bytes ) throws InvalidKeySpecException, NoSuchAlgorithmException { return KeyFactory.getInstance( algorithm.getValue() ).generatePublic( new X509EncodedKeySpec( bytes ) ); } }