com.vmware.o11n.plugin.crypto.service.CryptoRSAService.java Source code

Java tutorial

Introduction

Here is the source code for com.vmware.o11n.plugin.crypto.service.CryptoRSAService.java

Source

/*
 * Copyright (c) 2017 VMware, Inc. All Rights Reserved.
 * SPDX-License-Identifier: BSD-2-Clause
 */
package com.vmware.o11n.plugin.crypto.service;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;

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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.vmware.o11n.plugin.crypto.model.CryptoUtil;

@Component
public class CryptoRSAService {
    private final Logger log = LoggerFactory.getLogger(CryptoRSAService.class);

    private static final String CIPHER_TRANSFORMATION = "RSA/ECB/PKCS1Padding";
    private static final String SIGNATURE_ALGORITHM = "NONEwithRSA";

    /**
     * RSA Encryption
     *
     * @param pemKey RSA Key (Public or Private, Public will be derived from Private)
     * @param dataB64 Data encoded with Base64 to encrypt
     * @return Encrypted data Base64 encoded
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public String encrypt(String pemKey, String dataB64)
            throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        String encryptedB64 = null;
        PublicKey publicKey = null;

        Key key = null;
        try {
            key = CryptoUtil.getKey(pemKey); //can be private or public
        } catch (IOException e) {
            //try to fix key:
            key = CryptoUtil.getKey(CryptoUtil.fixPemString(pemKey));
        }
        if (key instanceof RSAPublicKey) {
            publicKey = (RSAPublicKey) key;
        } else if (key instanceof RSAPrivateCrtKey) {
            RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) key;
            publicKey = CryptoUtil.getPublicFromPrivate(privateKey);
        } else {
            throw new IllegalArgumentException("Unknown key object type: " + key.getClass().getName());
        }

        Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        encryptedB64 = Base64.encodeBase64String(cipher.doFinal(Base64.decodeBase64(dataB64)));
        return encryptedB64;
    }

    /**
     * RSA Decryption
     *
     * @param pemKey RSA Private Key
     * @param encryptedB64 RSA Encrypted data encoded with Base64
     * @return Original data Base64 Encoded
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public String decrypt(String pemKey, String encryptedB64)
            throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        String dataB64 = null;
        PrivateKey privateKey = null;
        Key key = null;
        try {
            key = CryptoUtil.getKey(pemKey);
        } catch (IOException e) {
            //try to fix key:
            key = CryptoUtil.getKey(CryptoUtil.fixPemString(pemKey));
        }
        if (key instanceof PrivateKey) {
            privateKey = (PrivateKey) key;
        } else {
            throw new IllegalArgumentException("Invalid key object type: " + key.getClass().getName());
        }

        Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        dataB64 = Base64.encodeBase64String(cipher.doFinal(Base64.decodeBase64(encryptedB64)));
        return dataB64;
    }

    /**
     * Creates an RSA Signature
     *
     * @param pemKey RSA Private Key
     * @param dataB64 Base64 encoded data to sign
     * @return Base64 encoded signature
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws IOException
     * @throws InvalidKeyException
     * @throws SignatureException
     */
    public String sign(String pemKey, String dataB64) throws NoSuchAlgorithmException, InvalidKeySpecException,
            IOException, InvalidKeyException, SignatureException {
        String signatureB64 = null;
        PrivateKey privateKey = null;

        Key key = null;
        try {
            key = CryptoUtil.getKey(pemKey);
        } catch (IOException e) {
            //try to fix key:
            key = CryptoUtil.getKey(CryptoUtil.fixPemString(pemKey));
        }
        if (key instanceof PrivateKey) {
            privateKey = (PrivateKey) key;
        } else {
            throw new IllegalArgumentException("Invalid key object type: " + key.getClass().getName());
        }

        Signature signer = Signature.getInstance(SIGNATURE_ALGORITHM);
        signer.initSign(privateKey);
        signer.update(Base64.decodeBase64(dataB64));
        byte[] sigBytes = signer.sign();
        signatureB64 = Base64.encodeBase64String(sigBytes);

        return signatureB64;
    }

    /**
     * Verify a RSA Signature with a RSA Public Key
     *
     * @param pemKey RSA Key (Public or Private, Public will be derived from Private)
     * @param dataB64 Base64 encoded data the signature was created from
     * @param signatureB64 Base64 Encoded RSA Signature to verify
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws IOException
     * @throws InvalidKeyException
     * @throws SignatureException
     */
    public boolean verifySignature(String pemKey, String dataB64, String signatureB64)
            throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, InvalidKeyException,
            SignatureException {
        boolean valid = false;
        PublicKey publicKey = null;

        Key key = null;
        try {
            key = CryptoUtil.getKey(pemKey); //can be private or public
        } catch (IOException e) {
            //try to fix key:
            key = CryptoUtil.getKey(CryptoUtil.fixPemString(pemKey));
        }

        if (key instanceof RSAPublicKey) {
            publicKey = (RSAPublicKey) key;
        } else if (key instanceof RSAPrivateCrtKey) {
            RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) key;
            publicKey = CryptoUtil.getPublicFromPrivate(privateKey);
        } else {
            throw new IllegalArgumentException("Unknown key object type: " + key.getClass().getName());
        }

        Signature signer = Signature.getInstance(SIGNATURE_ALGORITHM);
        signer.initVerify(publicKey);
        signer.update(Base64.decodeBase64(dataB64));
        valid = signer.verify(Base64.decodeBase64(signatureB64));

        return valid;
    }
}