001package co.codewizards.cloudstore.core.auth;
002
003import static java.util.Objects.*;
004
005import java.security.KeyFactory;
006import java.security.PrivateKey;
007import java.security.spec.EncodedKeySpec;
008import java.security.spec.PKCS8EncodedKeySpec;
009
010import javax.crypto.Cipher;
011import javax.crypto.spec.IvParameterSpec;
012import javax.crypto.spec.SecretKeySpec;
013
014public class SignedAuthTokenDecrypter {
015        private PrivateKey privateKey;
016
017        public SignedAuthTokenDecrypter(final byte[] privateKeyData) {
018                requireNonNull(privateKeyData, "privateKeyData");
019                BouncyCastleRegistrationUtil.registerBouncyCastleIfNeeded();
020                try {
021                        final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
022                        final EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyData);
023                        this.privateKey = keyFactory.generatePrivate(privateKeySpec);
024                } catch (final RuntimeException e) {
025                        throw e;
026                } catch (final Exception e) {
027                        throw new RuntimeException(e);
028                }
029        }
030
031        public byte[] decrypt(final EncryptedSignedAuthToken encryptedSignedAuthToken) {
032                requireNonNull(encryptedSignedAuthToken, "encryptedSignedAuthToken");
033                requireNonNull(encryptedSignedAuthToken.getEncryptedSignedAuthTokenData(), "encryptedSignedAuthToken.encryptedSignedAuthTokenData");
034                requireNonNull(encryptedSignedAuthToken.getEncryptedSymmetricKey(), "encryptedSignedAuthToken.encryptedSymmetricKey");
035                try {
036                        final Cipher asymCipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA1ANDMGF1PADDING");
037                        asymCipher.init(Cipher.DECRYPT_MODE, privateKey);
038                        final byte[] symKey = asymCipher.doFinal(encryptedSignedAuthToken.getEncryptedSymmetricKey());
039
040                        final Cipher symCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
041                        symCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(symKey, "AES"),
042                                        new IvParameterSpec(encryptedSignedAuthToken.getEncryptedSignedAuthTokenDataIV()));
043
044                        final byte[] signedAuthTokenData = symCipher.doFinal(encryptedSignedAuthToken.getEncryptedSignedAuthTokenData());
045
046                        return signedAuthTokenData;
047                } catch (final RuntimeException e) {
048                        throw e;
049                } catch (final Exception e) {
050                        throw new RuntimeException(e);
051                }
052        }
053}