Java tutorial
/** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for * license information. */ package com.microsoft.azure.keyvault.cryptography; import java.io.IOException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.interfaces.RSAPublicKey; import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Triple; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.microsoft.azure.keyvault.core.IKey; import com.microsoft.azure.keyvault.cryptography.algorithms.Rs256; import com.microsoft.azure.keyvault.cryptography.algorithms.RsaOaep; import com.microsoft.azure.keyvault.cryptography.Strings; public class RsaKey implements IKey { public static int KeySize1024 = 1024; public static int KeySize2048 = 2048; public static int getDefaultKeySize() { return RsaKey.KeySize2048; } private final String _kid; private final KeyPair _keyPair; private final Provider _provider; public RsaKey(String kid) throws NoSuchAlgorithmException { this(kid, getDefaultKeySize()); } public RsaKey(String kid, int keySize) throws NoSuchAlgorithmException { this(kid, keySize, null); } public RsaKey(String kid, int keySize, Provider provider) throws NoSuchAlgorithmException { if (Strings.isNullOrWhiteSpace(kid)) { throw new IllegalArgumentException("kid"); } final KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", provider); generator.initialize(keySize); _kid = kid; _keyPair = generator.generateKeyPair(); _provider = provider; } public RsaKey(String kid, KeyPair keyPair) { this(kid, keyPair, null); } public RsaKey(String kid, KeyPair keyPair, Provider provider) { if (Strings.isNullOrWhiteSpace(kid)) { throw new IllegalArgumentException("kid"); } if (keyPair == null) { throw new IllegalArgumentException("kid"); } if (keyPair.getPublic() == null || !(keyPair.getPublic() instanceof RSAPublicKey)) { throw new IllegalArgumentException("keyPair"); } _kid = kid; _keyPair = keyPair; _provider = provider; } @Override public String getDefaultEncryptionAlgorithm() { return RsaOaep.ALGORITHM_NAME; } @Override public String getDefaultKeyWrapAlgorithm() { return RsaOaep.ALGORITHM_NAME; } @Override public String getDefaultSignatureAlgorithm() { return Rs256.ALGORITHM_NAME; } @Override public String getKid() { return _kid; } @Override public ListenableFuture<byte[]> decryptAsync(final byte[] ciphertext, final byte[] iv, final byte[] authenticationData, final byte[] authenticationTag, final String algorithm) throws NoSuchAlgorithmException { if (ciphertext == null) { throw new IllegalArgumentException("ciphertext"); } // Interpret the requested algorithm if (Strings.isNullOrWhiteSpace(algorithm)) { throw new IllegalArgumentException("algorithm"); } Algorithm baseAlgorithm = AlgorithmResolver.Default.get(algorithm); if (baseAlgorithm == null || !(baseAlgorithm instanceof AsymmetricEncryptionAlgorithm)) { throw new NoSuchAlgorithmException(algorithm); } AsymmetricEncryptionAlgorithm algo = (AsymmetricEncryptionAlgorithm) baseAlgorithm; ICryptoTransform transform; ListenableFuture<byte[]> result; try { transform = algo.CreateDecryptor(_keyPair, _provider); result = Futures.immediateFuture(transform.doFinal(ciphertext)); } catch (Exception e) { result = Futures.immediateFailedFuture(e); } return result; } @Override public ListenableFuture<Triple<byte[], byte[], String>> encryptAsync(final byte[] plaintext, final byte[] iv, final byte[] authenticationData, final String algorithm) throws NoSuchAlgorithmException { if (plaintext == null) { throw new IllegalArgumentException("plaintext"); } // Interpret the requested algorithm String algorithmName = (Strings.isNullOrWhiteSpace(algorithm) ? getDefaultEncryptionAlgorithm() : algorithm); Algorithm baseAlgorithm = AlgorithmResolver.Default.get(algorithmName); if (baseAlgorithm == null || !(baseAlgorithm instanceof AsymmetricEncryptionAlgorithm)) { throw new NoSuchAlgorithmException(algorithmName); } AsymmetricEncryptionAlgorithm algo = (AsymmetricEncryptionAlgorithm) baseAlgorithm; ICryptoTransform transform; ListenableFuture<Triple<byte[], byte[], String>> result; try { transform = algo.CreateEncryptor(_keyPair, _provider); result = Futures.immediateFuture(Triple.of(transform.doFinal(plaintext), (byte[]) null, algorithmName)); } catch (Exception e) { result = Futures.immediateFailedFuture(e); } return result; } @Override public ListenableFuture<Pair<byte[], String>> wrapKeyAsync(final byte[] key, final String algorithm) throws NoSuchAlgorithmException { if (key == null) { throw new IllegalArgumentException("key"); } // Interpret the requested algorithm String algorithmName = (Strings.isNullOrWhiteSpace(algorithm) ? getDefaultKeyWrapAlgorithm() : algorithm); Algorithm baseAlgorithm = AlgorithmResolver.Default.get(algorithmName); if (baseAlgorithm == null || !(baseAlgorithm instanceof AsymmetricEncryptionAlgorithm)) { throw new NoSuchAlgorithmException(algorithmName); } AsymmetricEncryptionAlgorithm algo = (AsymmetricEncryptionAlgorithm) baseAlgorithm; ICryptoTransform transform; ListenableFuture<Pair<byte[], String>> result; try { transform = algo.CreateEncryptor(_keyPair, _provider); result = Futures.immediateFuture(Pair.of(transform.doFinal(key), algorithmName)); } catch (Exception e) { result = Futures.immediateFailedFuture(e); } return result; } @Override public ListenableFuture<byte[]> unwrapKeyAsync(final byte[] encryptedKey, final String algorithm) throws NoSuchAlgorithmException { if (encryptedKey == null) { throw new IllegalArgumentException("encryptedKey "); } // Interpret the requested algorithm if (Strings.isNullOrWhiteSpace(algorithm)) { throw new IllegalArgumentException("algorithm"); } // Interpret the requested algorithm Algorithm baseAlgorithm = AlgorithmResolver.Default.get(algorithm); if (baseAlgorithm == null || !(baseAlgorithm instanceof AsymmetricEncryptionAlgorithm)) { throw new NoSuchAlgorithmException(algorithm); } AsymmetricEncryptionAlgorithm algo = (AsymmetricEncryptionAlgorithm) baseAlgorithm; ICryptoTransform transform; ListenableFuture<byte[]> result; try { transform = algo.CreateDecryptor(_keyPair, _provider); result = Futures.immediateFuture(transform.doFinal(encryptedKey)); } catch (Exception e) { result = Futures.immediateFailedFuture(e); } return result; } @Override public ListenableFuture<Pair<byte[], String>> signAsync(final byte[] digest, final String algorithm) throws NoSuchAlgorithmException { if (digest == null) { throw new IllegalArgumentException("encryptedKey "); } // Interpret the requested algorithm if (Strings.isNullOrWhiteSpace(algorithm)) { throw new IllegalArgumentException("algorithm"); } // Interpret the requested algorithm Algorithm baseAlgorithm = AlgorithmResolver.Default.get(algorithm); if (baseAlgorithm == null || !(baseAlgorithm instanceof AsymmetricSignatureAlgorithm)) { throw new NoSuchAlgorithmException(algorithm); } Rs256 algo = (Rs256) baseAlgorithm; ISignatureTransform signer = algo.createSignatureTransform(_keyPair); try { return Futures.immediateFuture(Pair.of(signer.sign(digest), Rs256.ALGORITHM_NAME)); } catch (Exception e) { return Futures.immediateFailedFuture(e); } } @Override public ListenableFuture<Boolean> verifyAsync(final byte[] digest, final byte[] signature, final String algorithm) throws NoSuchAlgorithmException { if (digest == null) { throw new IllegalArgumentException("encryptedKey "); } // Interpret the requested algorithm if (Strings.isNullOrWhiteSpace(algorithm)) { throw new IllegalArgumentException("algorithm"); } // Interpret the requested algorithm Algorithm baseAlgorithm = AlgorithmResolver.Default.get(algorithm); if (baseAlgorithm == null || !(baseAlgorithm instanceof AsymmetricSignatureAlgorithm)) { throw new NoSuchAlgorithmException(algorithm); } Rs256 algo = (Rs256) baseAlgorithm; ISignatureTransform signer = algo.createSignatureTransform(_keyPair); try { return Futures.immediateFuture(signer.verify(digest, signature)); } catch (Exception e) { return Futures.immediateFailedFuture(e); } } @Override public void close() throws IOException { // Intentionally empty } }