Search in sources :

Example 1 with EncryptedValue

use of com.github.zhenwei.pkix.util.asn1.crmf.EncryptedValue in project LinLong-Java by zhenwei1108.

the class EncryptedValueBuilder method encryptData.

private EncryptedValue encryptData(byte[] data) throws CRMFException {
    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    OutputStream eOut = encryptor.getOutputStream(bOut);
    try {
        eOut.write(data);
        eOut.close();
    } catch (IOException e) {
        throw new CRMFException("cannot process data: " + e.getMessage(), e);
    }
    AlgorithmIdentifier intendedAlg = null;
    AlgorithmIdentifier symmAlg = encryptor.getAlgorithmIdentifier();
    DERBitString encSymmKey;
    try {
        wrapper.generateWrappedKey(encryptor.getKey());
        encSymmKey = new DERBitString(wrapper.generateWrappedKey(encryptor.getKey()));
    } catch (OperatorException e) {
        throw new CRMFException("cannot wrap key: " + e.getMessage(), e);
    }
    AlgorithmIdentifier keyAlg = wrapper.getAlgorithmIdentifier();
    ASN1OctetString valueHint = null;
    DERBitString encValue = new DERBitString(bOut.toByteArray());
    return new EncryptedValue(intendedAlg, symmAlg, encSymmKey, keyAlg, valueHint, encValue);
}
Also used : ASN1OctetString(com.github.zhenwei.core.asn1.ASN1OctetString) OutputStream(java.io.OutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) DERBitString(com.github.zhenwei.core.asn1.DERBitString) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) EncryptedValue(com.github.zhenwei.pkix.util.asn1.crmf.EncryptedValue) OperatorException(com.github.zhenwei.pkix.operator.OperatorException) AlgorithmIdentifier(com.github.zhenwei.core.asn1.x509.AlgorithmIdentifier)

Example 2 with EncryptedValue

use of com.github.zhenwei.pkix.util.asn1.crmf.EncryptedValue in project LinLong-Java by zhenwei1108.

the class EncryptedValueBuilder method build.

/**
 * Build an EncryptedValue structure containing the private key contained in the passed info
 * structure.
 *
 * @param privateKeyInfo a PKCS#8 private key info structure.
 * @return an EncryptedValue containing an EncryptedPrivateKeyInfo structure.
 * @throws CRMFException on a failure to encrypt the data, or wrap the symmetric key for this
 *                       value.
 */
public EncryptedValue build(PrivateKeyInfo privateKeyInfo) throws CRMFException {
    PKCS8EncryptedPrivateKeyInfoBuilder encInfoBldr = new PKCS8EncryptedPrivateKeyInfoBuilder(privateKeyInfo);
    AlgorithmIdentifier intendedAlg = privateKeyInfo.getPrivateKeyAlgorithm();
    AlgorithmIdentifier symmAlg = encryptor.getAlgorithmIdentifier();
    DERBitString encSymmKey;
    try {
        PKCS8EncryptedPrivateKeyInfo encInfo = encInfoBldr.build(encryptor);
        encSymmKey = new DERBitString(wrapper.generateWrappedKey(encryptor.getKey()));
        AlgorithmIdentifier keyAlg = wrapper.getAlgorithmIdentifier();
        ASN1OctetString valueHint = null;
        return new EncryptedValue(intendedAlg, symmAlg, encSymmKey, keyAlg, valueHint, new DERBitString(encInfo.getEncryptedData()));
    } catch (IllegalStateException e) {
        throw new CRMFException("cannot encode key: " + e.getMessage(), e);
    } catch (OperatorException e) {
        throw new CRMFException("cannot wrap key: " + e.getMessage(), e);
    }
}
Also used : ASN1OctetString(com.github.zhenwei.core.asn1.ASN1OctetString) PKCS8EncryptedPrivateKeyInfoBuilder(com.github.zhenwei.pkix.pkcs.PKCS8EncryptedPrivateKeyInfoBuilder) DERBitString(com.github.zhenwei.core.asn1.DERBitString) PKCS8EncryptedPrivateKeyInfo(com.github.zhenwei.pkix.pkcs.PKCS8EncryptedPrivateKeyInfo) EncryptedValue(com.github.zhenwei.pkix.util.asn1.crmf.EncryptedValue) OperatorException(com.github.zhenwei.pkix.operator.OperatorException) AlgorithmIdentifier(com.github.zhenwei.core.asn1.x509.AlgorithmIdentifier)

Example 3 with EncryptedValue

use of com.github.zhenwei.pkix.util.asn1.crmf.EncryptedValue 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

ASN1OctetString (com.github.zhenwei.core.asn1.ASN1OctetString)2 DERBitString (com.github.zhenwei.core.asn1.DERBitString)2 AlgorithmIdentifier (com.github.zhenwei.core.asn1.x509.AlgorithmIdentifier)2 OperatorException (com.github.zhenwei.pkix.operator.OperatorException)2 EncryptedValue (com.github.zhenwei.pkix.util.asn1.crmf.EncryptedValue)2 PKCS8EncryptedPrivateKeyInfo (com.github.zhenwei.pkix.pkcs.PKCS8EncryptedPrivateKeyInfo)1 PKCS8EncryptedPrivateKeyInfoBuilder (com.github.zhenwei.pkix.pkcs.PKCS8EncryptedPrivateKeyInfoBuilder)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1 OutputStream (java.io.OutputStream)1 ECPublicKey (java.security.interfaces.ECPublicKey)1 RSAPublicKey (java.security.interfaces.RSAPublicKey)1 GCMParameterSpec (javax.crypto.spec.GCMParameterSpec)1 SecretKeySpec (javax.crypto.spec.SecretKeySpec)1 GCMParameters (org.bouncycastle.asn1.cms.GCMParameters)1 EncryptedValue (org.bouncycastle.asn1.crmf.EncryptedValue)1 AlgorithmIdentifier (org.bouncycastle.asn1.x509.AlgorithmIdentifier)1 PBKDF2KeySpec (org.bouncycastle.jcajce.spec.PBKDF2KeySpec)1