Search in sources :

Example 1 with PBKDF2KeySpec

use of org.bouncycastle.jcajce.spec.PBKDF2KeySpec in project xipki by xipki.

the class CmpAgentUtil method decrypt.

private static byte[] decrypt(EncryptedValue ev, char[] password) throws XiSecurityException {
    AlgorithmIdentifier symmAlg = ev.getSymmAlg();
    if (!PKCSObjectIdentifiers.id_PBES2.equals(symmAlg.getAlgorithm())) {
        throw new XiSecurityException("unsupported symmAlg " + symmAlg.getAlgorithm().getId());
    }
    PBES2Parameters alg = PBES2Parameters.getInstance(symmAlg.getParameters());
    PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters());
    AlgorithmIdentifier encScheme = AlgorithmIdentifier.getInstance(alg.getEncryptionScheme());
    try {
        SecretKeyFactory keyFact = SecretKeyFactory.getInstance(alg.getKeyDerivationFunc().getAlgorithm().getId());
        SecretKey key;
        int iterations = func.getIterationCount().intValue();
        key = keyFact.generateSecret(new PBKDF2KeySpec(password, func.getSalt(), iterations, KEYSIZE_PROVIDER.getKeySize(encScheme), func.getPrf()));
        key = new SecretKeySpec(key.getEncoded(), "AES");
        String cipherAlgOid = alg.getEncryptionScheme().getAlgorithm().getId();
        Cipher cipher = Cipher.getInstance(cipherAlgOid);
        ASN1Encodable encParams = alg.getEncryptionScheme().getParameters();
        GCMParameters gcmParameters = GCMParameters.getInstance(encParams);
        GCMParameterSpec gcmParamSpec = new GCMParameterSpec(gcmParameters.getIcvLen() * 8, gcmParameters.getNonce());
        cipher.init(Cipher.DECRYPT_MODE, key, gcmParamSpec);
        return cipher.doFinal(ev.getEncValue().getOctets());
    } catch (IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException ex) {
        throw new XiSecurityException("Error while decrypting the EncryptedValue", ex);
    }
}
Also used : PBES2Parameters(org.bouncycastle.asn1.pkcs.PBES2Parameters) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) PBKDF2KeySpec(org.bouncycastle.jcajce.spec.PBKDF2KeySpec) InvalidKeyException(java.security.InvalidKeyException) GCMParameters(org.bouncycastle.asn1.cms.GCMParameters) SecretKeySpec(javax.crypto.spec.SecretKeySpec) PBKDF2Params(org.bouncycastle.asn1.pkcs.PBKDF2Params) IESCipher(org.bouncycastle.jcajce.provider.asymmetric.ec.IESCipher) BlockCipher(org.bouncycastle.crypto.BlockCipher) CBCBlockCipher(org.bouncycastle.crypto.modes.CBCBlockCipher) PaddedBufferedBlockCipher(org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher) InvalidKeySpecException(java.security.spec.InvalidKeySpecException)

Example 2 with PBKDF2KeySpec

use of org.bouncycastle.jcajce.spec.PBKDF2KeySpec in project xipki by xipki.

the class PbmMacCmpCaClient method decrypt.

private byte[] decrypt(EncryptedValue ev) throws Exception {
    AlgorithmIdentifier symmAlg = ev.getSymmAlg();
    if (!PKCSObjectIdentifiers.id_PBES2.equals(symmAlg.getAlgorithm())) {
        throw new Exception("unsupported symmAlg " + symmAlg.getAlgorithm().getId());
    }
    PBES2Parameters alg = PBES2Parameters.getInstance(symmAlg.getParameters());
    PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters());
    AlgorithmIdentifier encScheme = AlgorithmIdentifier.getInstance(alg.getEncryptionScheme());
    ASN1ObjectIdentifier encSchemaAlgOid = encScheme.getAlgorithm();
    int keysizeInBit;
    if (NISTObjectIdentifiers.id_aes128_GCM.equals(encSchemaAlgOid)) {
        keysizeInBit = 128;
    } else if (NISTObjectIdentifiers.id_aes192_GCM.equals(encSchemaAlgOid)) {
        keysizeInBit = 192;
    } else if (NISTObjectIdentifiers.id_aes256_GCM.equals(encSchemaAlgOid)) {
        keysizeInBit = 256;
    } else {
        throw new Exception("unsupported encryption scheme " + encSchemaAlgOid.getId());
    }
    SecretKeyFactory keyFact = SecretKeyFactory.getInstance(alg.getKeyDerivationFunc().getAlgorithm().getId());
    SecretKey key;
    int iterations = func.getIterationCount().intValue();
    key = keyFact.generateSecret(new PBKDF2KeySpec(password, func.getSalt(), iterations, keysizeInBit, func.getPrf()));
    key = new SecretKeySpec(key.getEncoded(), "AES");
    String cipherAlgOid = alg.getEncryptionScheme().getAlgorithm().getId();
    Cipher cipher = Cipher.getInstance(cipherAlgOid);
    ASN1Encodable encParams = alg.getEncryptionScheme().getParameters();
    GCMParameters gcmParameters = GCMParameters.getInstance(encParams);
    GCMParameterSpec gcmParamSpec = new GCMParameterSpec(gcmParameters.getIcvLen() * 8, gcmParameters.getNonce());
    cipher.init(Cipher.DECRYPT_MODE, key, gcmParamSpec);
    return cipher.doFinal(ev.getEncValue().getOctets());
}
Also used : PBES2Parameters(org.bouncycastle.asn1.pkcs.PBES2Parameters) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) PBKDF2KeySpec(org.bouncycastle.jcajce.spec.PBKDF2KeySpec) CMPException(org.bouncycastle.cert.cmp.CMPException) CRMFException(org.bouncycastle.cert.crmf.CRMFException) InvalidKeyException(java.security.InvalidKeyException) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) SecretKey(javax.crypto.SecretKey) GCMParameters(org.bouncycastle.asn1.cms.GCMParameters) SecretKeySpec(javax.crypto.spec.SecretKeySpec) PBKDF2Params(org.bouncycastle.asn1.pkcs.PBKDF2Params) Cipher(javax.crypto.Cipher) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) SecretKeyFactory(javax.crypto.SecretKeyFactory) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Example 3 with PBKDF2KeySpec

use of org.bouncycastle.jcajce.spec.PBKDF2KeySpec in project xipki by xipki.

the class BaseCmpResponder method postProcessCertInfo.

protected CertResponse postProcessCertInfo(ASN1Integer certReqId, CmpRequestorInfo requestor, CertificateInfo certInfo) {
    String warningMsg = certInfo.getWarningMessage();
    PKIStatusInfo statusInfo;
    if (StringUtil.isBlank(warningMsg)) {
        statusInfo = certInfo.isAlreadyIssued() ? new PKIStatusInfo(PKIStatus.grantedWithMods, new PKIFreeText("ALREADY_ISSUED")) : new PKIStatusInfo(PKIStatus.granted);
    } else {
        statusInfo = new PKIStatusInfo(PKIStatus.grantedWithMods, new PKIFreeText(warningMsg));
    }
    CertOrEncCert cec = new CertOrEncCert(new CMPCertificate(certInfo.getCert().getCert().toBcCert().toASN1Structure()));
    if (certInfo.getPrivateKey() == null) {
        // no private key will be returned.
        return new CertResponse(certReqId, statusInfo, new CertifiedKeyPair(cec), null);
    }
    final int aesGcmTagByteLen = 16;
    final int aesGcmNonceLen = 12;
    PrivateKeyInfo privKey = certInfo.getPrivateKey();
    AlgorithmIdentifier intendedAlg = privKey.getPrivateKeyAlgorithm();
    EncryptedValue encKey;
    // we cannot use BoucyCastle's EncryptedValueBuilder to build the EncryptedValue.
    try {
        if (requestor.getCert() != null) {
            // use private key of the requestor to encrypt the private key
            PublicKey reqPub = requestor.getCert().getCert().getPublicKey();
            CrmfKeyWrapper wrapper;
            if (reqPub instanceof RSAPublicKey) {
                wrapper = new CrmfKeyWrapper.RSAOAEPAsymmetricKeyWrapper(reqPub);
            } else if (reqPub instanceof ECPublicKey) {
                wrapper = new CrmfKeyWrapper.ECIESAsymmetricKeyWrapper(reqPub);
            } else {
                String msg = "Requestors's private key can not be used for encryption";
                LOG.error(msg);
                return new CertResponse(certReqId, new PKIStatusInfo(PKIStatus.rejection, new PKIFreeText(msg)));
            }
            byte[] symmKeyBytes;
            synchronized (aesKeyGen) {
                symmKeyBytes = aesKeyGen.generateKey().getEncoded();
            }
            // encrypt the symmKey
            byte[] encSymmKey = wrapper.generateWrappedKey(symmKeyBytes);
            // algorithmIdentifier after the encryption process.
            AlgorithmIdentifier keyAlg = wrapper.getAlgorithmIdentifier();
            // encrypt the data
            ASN1ObjectIdentifier symmAlgOid = NISTObjectIdentifiers.id_aes128_GCM;
            byte[] nonce = randomBytes(aesGcmNonceLen);
            ConcurrentBagEntry<Cipher> cipher0 = null;
            if (aesGcm_ciphers_initialized) {
                try {
                    cipher0 = aesGcm_ciphers.borrow(5, TimeUnit.SECONDS);
                } catch (InterruptedException ex) {
                }
            }
            Cipher dataCipher = (cipher0 != null) ? cipher0.value() : Cipher.getInstance(symmAlgOid.getId());
            byte[] encValue;
            try {
                try {
                    dataCipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(symmKeyBytes, "AES"), new GCMParameterSpec(aesGcmTagByteLen << 3, nonce));
                } catch (InvalidKeyException | InvalidAlgorithmParameterException ex) {
                    throw new IllegalStateException(ex);
                }
                encValue = dataCipher.doFinal(privKey.getEncoded());
            } finally {
                if (cipher0 != null) {
                    aesGcm_ciphers.requite(cipher0);
                }
            }
            GCMParameters params = new GCMParameters(nonce, aesGcmTagByteLen);
            AlgorithmIdentifier symmAlg = new AlgorithmIdentifier(symmAlgOid, params);
            encKey = new EncryptedValue(intendedAlg, symmAlg, new DERBitString(encSymmKey), keyAlg, null, new DERBitString(encValue));
        } else {
            final ASN1ObjectIdentifier encAlgOid = NISTObjectIdentifiers.id_aes128_GCM;
            // one of 128, 192 and 256. Must match the encAlgOid
            final int keysizeBits = 128;
            // >= 1000
            final int iterCount = 10240;
            // fixed value
            final int nonceLen = 12;
            // fixed value
            final int tagByteLen = 16;
            byte[] nonce = randomBytes(nonceLen);
            // use password of the requestor to encrypt the private key
            byte[] pbkdfSalt = randomBytes(keysizeBits / 8);
            ConcurrentBagEntry<SecretKeyFactory> keyFact0 = null;
            if (pbkdf2_kdfs_initialized) {
                try {
                    keyFact0 = pbkdf2_kdfs.borrow(5, TimeUnit.SECONDS);
                } catch (InterruptedException ex) {
                }
            }
            SecretKeyFactory keyFact = (keyFact0 != null) ? keyFact0.value() : SecretKeyFactory.getInstance(PKCSObjectIdentifiers.id_PBKDF2.getId());
            SecretKey key;
            try {
                key = keyFact.generateSecret(new PBKDF2KeySpec(requestor.getPassword(), pbkdfSalt, iterCount, keysizeBits, prf_hmacWithSHA256));
                key = new SecretKeySpec(key.getEncoded(), "AES");
            } finally {
                if (keyFact0 != null) {
                    pbkdf2_kdfs.requite(keyFact0);
                }
            }
            GCMParameterSpec gcmParamSpec = new GCMParameterSpec(tagByteLen * 8, nonce);
            ConcurrentBagEntry<Cipher> cipher0 = null;
            if (aesGcm_ciphers_initialized) {
                try {
                    cipher0 = aesGcm_ciphers.borrow(5, TimeUnit.SECONDS);
                } catch (InterruptedException ex) {
                }
            }
            Cipher dataCipher = (cipher0 != null) ? cipher0.value() : Cipher.getInstance(encAlgOid.getId());
            byte[] encValue;
            try {
                dataCipher.init(Cipher.ENCRYPT_MODE, key, gcmParamSpec);
                encValue = dataCipher.doFinal(privKey.getEncoded());
            } finally {
                if (cipher0 != null) {
                    aesGcm_ciphers.requite(cipher0);
                }
            }
            AlgorithmIdentifier symmAlg = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBES2, new PBES2Parameters(new KeyDerivationFunc(PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(pbkdfSalt, iterCount, keysizeBits / 8, prf_hmacWithSHA256)), new EncryptionScheme(encAlgOid, new GCMParameters(nonce, tagByteLen))));
            encKey = new EncryptedValue(intendedAlg, symmAlg, null, null, null, new DERBitString(encValue));
        }
    } catch (Throwable th) {
        String msg = "error while encrypting the private key";
        LOG.error(msg);
        return new CertResponse(certReqId, new PKIStatusInfo(PKIStatus.rejection, new PKIFreeText(msg)));
    }
    return new CertResponse(certReqId, statusInfo, new CertifiedKeyPair(cec, encKey, null), null);
}
Also used : GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) PBKDF2KeySpec(org.bouncycastle.jcajce.spec.PBKDF2KeySpec) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) RSAPublicKey(java.security.interfaces.RSAPublicKey) SecretKeySpec(javax.crypto.spec.SecretKeySpec) EncryptedValue(org.bouncycastle.asn1.crmf.EncryptedValue) RSAPublicKey(java.security.interfaces.RSAPublicKey) ECPublicKey(java.security.interfaces.ECPublicKey) GCMParameters(org.bouncycastle.asn1.cms.GCMParameters) ECPublicKey(java.security.interfaces.ECPublicKey)

Aggregations

GCMParameterSpec (javax.crypto.spec.GCMParameterSpec)3 SecretKeySpec (javax.crypto.spec.SecretKeySpec)3 GCMParameters (org.bouncycastle.asn1.cms.GCMParameters)3 PBKDF2KeySpec (org.bouncycastle.jcajce.spec.PBKDF2KeySpec)3 InvalidKeyException (java.security.InvalidKeyException)2 PBES2Parameters (org.bouncycastle.asn1.pkcs.PBES2Parameters)2 PBKDF2Params (org.bouncycastle.asn1.pkcs.PBKDF2Params)2 AlgorithmIdentifier (org.bouncycastle.asn1.x509.AlgorithmIdentifier)2 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 ECPublicKey (java.security.interfaces.ECPublicKey)1 RSAPublicKey (java.security.interfaces.RSAPublicKey)1 InvalidKeySpecException (java.security.spec.InvalidKeySpecException)1 Cipher (javax.crypto.Cipher)1 SecretKey (javax.crypto.SecretKey)1 SecretKeyFactory (javax.crypto.SecretKeyFactory)1 ASN1Encodable (org.bouncycastle.asn1.ASN1Encodable)1 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)1 EncryptedValue (org.bouncycastle.asn1.crmf.EncryptedValue)1 CMPException (org.bouncycastle.cert.cmp.CMPException)1