com.identityx.clientSDK.base.KeyHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of IdentityXClientSDK Show documentation
Show all versions of IdentityXClientSDK Show documentation
Client SDK for IdentityX Rest Services
/*
* Copyright Daon.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.identityx.clientSDK.base;
import com.daon.identityx.rest.model.pojo.Token;
import com.identityx.auth.impl.keys.SharedSecretApiKey;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Date;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.X509Extension;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.util.PrivateKeyFactory;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder;
/**
* Helper class for managing decryption of the shared secret passed back in a {@link Token} object.
* When a request for a new token is made, RSA 2048 key pair is generated. The public key wrapped in a X509 certificate is sent over to the server
* in order to be used for encrypting the shared secret to be returned.
* The private key is then used to decrypt the shared secret so it can be used in subsequent calls to the Rest servcies.
*
*/
public class KeyHelper {
private KeyPair keyPair;
public KeyHelper() throws NoSuchAlgorithmException {
GenerateKeyPair();
}
/**
* Gets a string containing the base64 encoding of a X509 certificate containing a new public key ready to be used for the creation of a new token.
* @param cn common name to be used for the certificate
* @return
* @throws IOException
*/
public String getPublicKeyForTokenRequest(String cn) throws IOException {
//String publicKey = Base64.encodeBase64String(keyPair.getPublic().getEncoded());
String publicKey = Base64.encodeBase64String(generateCertificate(cn).getEncoded());
return publicKey;
}
/**
* Creates a {@link SharedSecretApiKey} from a {@link Token} object returned by one of the token services
* @param token {@link Token}
* @return {@link SharedSecretApiKey} ready to be used as a credential.
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public SharedSecretApiKey createFromToken(Token token) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
// decrypt the key
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
byte[] data = Base64.decodeBase64(token.getEncryptedSharedKey());
byte[] descryptedData = cipher.doFinal(data);
SharedSecretApiKey newApiKey = new SharedSecretApiKey();
newApiKey.setId(token.getId());
String base64Decrypted = Base64.encodeBase64String(descryptedData);
newApiKey.setSecret(base64Decrypted);
return newApiKey;
}
/**
* Generates a new RSA 2048 key pair
* @return
* @throws NoSuchAlgorithmException
*/
protected KeyPair GenerateKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.generateKeyPair();
return keyPair;
}
/**
* Creates a new X509 certificate
* @param cn the common name for the certificate
* @return
*/
protected Certificate generateCertificate(String cn) {
try {
Certificate result;
byte publicKeyBytes[] = keyPair.getPublic().getEncoded();
SubjectPublicKeyInfo subPkInfo = new SubjectPublicKeyInfo(ASN1Sequence.getInstance(publicKeyBytes));
X509v3CertificateBuilder builder = new X509v3CertificateBuilder(
new X500Name("CN=" + cn),
BigInteger.valueOf(new SecureRandom().nextLong()),
new Date(System.currentTimeMillis() - 10000),new Date(System.currentTimeMillis() + 24L * 3600 * 1000),
new X500Name("CN=" + cn),
subPkInfo);
builder.addExtension(X509Extension.basicConstraints, true, new BasicConstraints(false));
builder.addExtension(X509Extension.keyUsage,true,new KeyUsage(KeyUsage.dataEncipherment));
builder.addExtension(X509Extension.extendedKeyUsage,true,new ExtendedKeyUsage(KeyPurposeId.anyExtendedKeyUsage));
AlgorithmIdentifier sigAlgId=new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA");
AlgorithmIdentifier digAlgId=new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
AsymmetricKeyParameter privateKeyAsymKeyParam=PrivateKeyFactory.createKey(keyPair.getPrivate().getEncoded());
ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId,digAlgId).build(privateKeyAsymKeyParam);
X509CertificateHolder holder=builder.build(sigGen);
result = holder.toASN1Structure();
//byte publicKeyBytes1[] = xspec.getEncoded();
return result;
}
catch (Exception e) {
throw new RuntimeException("Cannot generate X509 certificate",e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy