Example usage for org.bouncycastle.jcajce.spec UserKeyingMaterialSpec UserKeyingMaterialSpec

List of usage examples for org.bouncycastle.jcajce.spec UserKeyingMaterialSpec UserKeyingMaterialSpec

Introduction

In this page you can find the example usage for org.bouncycastle.jcajce.spec UserKeyingMaterialSpec UserKeyingMaterialSpec.

Prototype

public UserKeyingMaterialSpec(byte[] userKeyingMaterial) 

Source Link

Usage

From source file:com.distrimind.util.crypto.EllipticCurveDiffieHellmanAlgorithm.java

License:Open Source License

private void setDistantPublicKey(byte[] distantPublicKeyBytes, SymmetricEncryptionType symmetricEncryptionType,
        SymmetricAuthentifiedSignatureType symmetricSignatureType, byte[] keyingMaterial)
        throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException,
        InvalidAlgorithmParameterException {
    CodeProvider.encureProviderLoaded(type.getCodeProvider());
    try {//from  w  ww. j  a v  a  2s  .c  o  m
        valid = false;
        if (distantPublicKeyBytes == null)
            throw new NullPointerException();
        if (keyingMaterial == null)
            throw new NullPointerException();
        if (keyingMaterial.length == 0)
            throw new IllegalArgumentException();
        if (derivedKey != null)
            throw new IllegalArgumentException(
                    "A key exchange process has already been begun. Use reset fonction before calling this function.");
        ASymmetricPublicKey distantPublicKey = (ASymmetricPublicKey) Key.decode(distantPublicKeyBytes);
        if (myKeyPair.getASymmetricPublicKey().equals(distantPublicKey))
            throw new InvalidKeyException("The local et distant public keys cannot be similar !");

        AbstractKeyAgreement ka;
        if (symmetricEncryptionType == null)
            ka = type.getKeyAgreementInstance(symmetricSignatureType);
        else
            ka = type.getKeyAgreementInstance(symmetricEncryptionType);
        if (type.isECCDHType() || type.isXDHType()) {

            UserKeyingMaterialSpec spec = null;
            if (type.useKDF())
                spec = new UserKeyingMaterialSpec(keyingMaterial);
            ka.init(myKeyPair.getASymmetricPrivateKey(), spec, randomForKeys);
        } else if (type.isECMQVType()) {
            throw new InternalError(
                    "Next code must use ephemeral and static keys. It must be completed/corrected.");
            /*ka.init(myKeyPair.getASymmetricPrivateKey(), new Object[] {
                  FipsEC.MQV.using(
                (AsymmetricECPublicKey)myKeyPair.getASymmetricPublicKey().toBouncyCastleKey(), (AsymmetricECPrivateKey)myKeyPair.getASymmetricPrivateKey().toBouncyCastleKey(), (AsymmetricECPublicKey)distantPublicKey.toBouncyCastleKey()),
                  keyingMaterial,
               }
            );*/
        }
        ka.doPhase(distantPublicKey, true);
        if (ka instanceof JavaNativeKeyAgreement)
            derivedKey = ka.generateSecretKey(keySizeBits);
        else
            derivedKey = ka.generateSecretKey((short) (keySizeBits / 8));
        valid = true;
    } catch (NoSuchAlgorithmException e) {
        throw new NoSuchAlgorithmException(e);
    } catch (NoSuchProviderException e) {
        throw new NoSuchAlgorithmException(e.getMessage());
    }
}

From source file:com.pazdev.jose.JWE.java

License:Apache License

public byte[] decrypt(int recipientIndex, Key decryptKey) {
    // steps 1 - 3 occur naturally

    // step 4/*  www . ja  va2  s.c o m*/
    Header ph, sh, rh;
    if (recipients != null && !recipients.isEmpty()) {
        rh = recipients.get(recipientIndex).header;
    } else {
        rh = header;
    }
    ph = getProtectedHeaderAsObject();
    sh = getUnprotectedHeader();
    Header joseHeader = Header.merge(ph, sh, rh);
    if (joseHeader.getCritical() != null && !joseHeader.getCritical().isEmpty()) {
        throw new UnsupportedOperationException("Cannot process critical elements");
    }

    // step 6
    Algorithm alg = joseHeader.getAlgorithm();
    Algorithm enc = joseHeader.getEncryptionAlgorithm();
    Algorithm zip = joseHeader.getCompressionAlgorithm();

    Key kek, cek;

    // step 7... how did we get this far without a key?

    if (Algorithm.ECDH_ES.equals(alg) || Algorithm.ECDH_ES_A128KW.equals(alg)
            || Algorithm.ECDH_ES_A192KW.equals(alg) || Algorithm.ECDH_ES_A256KW.equals(alg)) {
        // step 8
        JWK eph = joseHeader.getEphemeralPublicKey();
        Key publicKey = eph.getKeys().get("public");
        try {
            KeyAgreement ka = KeyAgreement.getInstance("ECCDHwithSHA256CKDF", "BC");
            byte[] apu = joseHeader.getAgreementPartyUInfo();
            byte[] apv = joseHeader.getAgreementPartyVInfo();
            if (apu == null) {
                apu = new byte[0];
            }
            if (apv == null) {
                apv = new byte[0];
            }
            Algorithm keyalg = alg;
            if (alg == Algorithm.ECDH_ES) {
                keyalg = enc;
            }
            int otherInfoSize = 0;
            otherInfoSize += 4 + keyalg.getName().length();
            otherInfoSize += 4 + apu.length;
            otherInfoSize += 4 + apv.length;
            otherInfoSize += 4; // SuppPubInfo
            byte[] otherInfo = new byte[otherInfoSize];
            ByteBuffer buf = ByteBuffer.wrap(otherInfo);
            buf.putInt(keyalg.getName().length());
            buf.put(keyalg.getName().getBytes(StandardCharsets.US_ASCII));
            buf.putInt(apu.length);
            buf.put(apu);
            buf.putInt(apv.length);
            buf.put(apv);
            buf.putInt(keyalg.getByteSize());
            UserKeyingMaterialSpec spec = new UserKeyingMaterialSpec(otherInfo);
            ka.init(decryptKey, spec);
            ka.doPhase(publicKey, true);
            // multiplying bit size by 8 to resolve a bug in Bouncy Castle
            // refer to org.bouncycastle.jcajce.provider.asymmetric.util.BaseAgreementSpi.java:179
            // and org.bouncycastle.jcajce.provider.asymmetric.util.BaseAgreementSpi.java:263
            SecretKey sharedKey = ka.generateSecret(String.format("AES[%d]", keyalg.getBitSize() * 8));
            if (Algorithm.ECDH_ES.equals(alg)) {
                kek = null;
                cek = sharedKey;
            } else {
                kek = sharedKey;
                cek = null;
            }
        } catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | NoSuchProviderException
                | InvalidKeyException e) {
            throw new RuntimeException(e);
        }
    } else if (Algorithm.RSA1_5.equals(alg) || Algorithm.RSA_OAEP.equals(alg)
            || Algorithm.RSA_OAEP_256.equals(alg) || Algorithm.A128KW.equals(alg)
            || Algorithm.A192KW.equals(alg) || Algorithm.A256KW.equals(alg) || Algorithm.A128GCMKW.equals(alg)
            || Algorithm.A192GCMKW.equals(alg) || Algorithm.A256GCMKW.equals(alg)
            || Algorithm.PBES2_HS256_A128KW.equals(alg) || Algorithm.PBES2_HS384_A192KW.equals(alg)
            || Algorithm.PBES2_HS512_A256KW.equals(alg)) {
        kek = decryptKey;
        cek = null;
    } else if (Algorithm.DIR.equals(alg)) {
        // step 11
        kek = null;
        cek = decryptKey;
    } else {
        throw new UnsupportedOperationException();
    }

    byte[] encryptedCEK;
    if (recipients != null) {
        encryptedCEK = recipients.get(recipientIndex).encryptedKey;
    } else {
        encryptedCEK = encryptedKey;
    }

    // step 9
    try {
        if (Algorithm.RSA1_5.equals(alg)) {
            Cipher c = Cipher.getInstance("RSA/NONE/PKCS1Padding", "BC");
            c.init(Cipher.UNWRAP_MODE, kek);
            cek = c.unwrap(encryptedCEK, "AES", Cipher.SECRET_KEY);
        } else if (Algorithm.RSA_OAEP.equals(alg)) {
            Cipher c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC");
            c.init(Cipher.UNWRAP_MODE, kek);
            cek = c.unwrap(encryptedCEK, "AES", Cipher.SECRET_KEY);
        } else if (Algorithm.RSA_OAEP_256.equals(alg)) {
            Cipher c = Cipher.getInstance("RSA/NONE/OAEPWithSHA256AndMGF1Padding", "BC");
            c.init(Cipher.UNWRAP_MODE, kek);
            cek = c.unwrap(encryptedCEK, "AES", Cipher.SECRET_KEY);
        } else if (Algorithm.A128KW.equals(alg) || Algorithm.A128KW.equals(alg) || Algorithm.A256KW.equals(alg)
                || Algorithm.ECDH_ES_A128KW.equals(alg) || Algorithm.ECDH_ES_A192KW.equals(alg)
                || Algorithm.ECDH_ES_A256KW.equals(alg) || Algorithm.PBES2_HS256_A128KW.equals(alg)
                || Algorithm.PBES2_HS384_A192KW.equals(alg) || Algorithm.PBES2_HS512_A256KW.equals(alg)) {
            Cipher c = Cipher.getInstance("AESWrap", "BC");
            c.init(Cipher.UNWRAP_MODE, kek);
            cek = c.unwrap(encryptedCEK, "AES", Cipher.SECRET_KEY);
        } else if (Algorithm.A128GCMKW.equals(alg) || Algorithm.A192GCMKW.equals(alg)
                || Algorithm.A256GCMKW.equals(alg)) {
            byte[] cipheredKey = new byte[encryptedCEK.length + 16];
            ByteBuffer buf = ByteBuffer.wrap(cipheredKey);
            buf.put(encryptedCEK);
            buf.put(joseHeader.getAuthenticationTag());
            Cipher c = Cipher.getInstance("AES/GCM/NoPadding", "BC");
            byte[] keyIV = joseHeader.getInitializationVector();
            c.init(Cipher.UNWRAP_MODE, kek, new GCMParameterSpec(128, keyIV));
            cek = c.unwrap(cipheredKey, "AES", Cipher.SECRET_KEY);
        }
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException | InvalidKeyException
            | InvalidAlgorithmParameterException e) {
        throw new RuntimeException(e);
    }

    // step 10
    if (Algorithm.DIR.equals(alg)
            || Algorithm.ECDH_ES.equals(alg) && encryptedCEK != null && encryptedCEK.length > 0) {
        throw new IllegalArgumentException("An encrypted key exists when direct algorithms are used");
    }

    // step 12
    if (cek == null) {
        throw new IllegalArgumentException("The content key cannot be found");
    }

    // step 13 is implemented by this method being called per recipient

    // step 14
    String protectedString = Base64.getUrlEncoder().withoutPadding().encodeToString(protectedHeader);

    // step 15
    byte[] jweAAD;
    if (aad != null && aad.length > 0) {
        String aadString = Base64.getUrlEncoder().withoutPadding().encodeToString(aad);
        jweAAD = String.format("%s.%s", protectedString, aadString).getBytes(StandardCharsets.US_ASCII);
    } else {
        jweAAD = protectedString.getBytes(StandardCharsets.US_ASCII);
    }

    byte[] output;
    // step 16
    try {
        if (Algorithm.A128CBC_HS256.equals(enc) || Algorithm.A192CBC_HS384.equals(enc)
                || Algorithm.A256CBC_HS512.equals(enc)) {
            byte[] k = cek.getEncoded();
            byte[] macKey = Arrays.copyOf(k, enc.getByteSize());
            byte[] encKey = Arrays.copyOfRange(k, enc.getByteSize(), k.length);

            byte[] al = new byte[Long.BYTES];
            ByteBuffer buf = ByteBuffer.wrap(al);
            buf.putLong((long) jweAAD.length);

            Mac mac;
            int tLen;
            if (Algorithm.A128CBC_HS256.equals(enc)) {
                mac = Mac.getInstance("HmacSHA256", "BC");
                mac.init(new SecretKeySpec(macKey, "HmacSHA256"));
                tLen = 16;
            } else if (Algorithm.A192CBC_HS384.equals(enc)) {
                mac = Mac.getInstance("HmacSHA384", "BC");
                mac.init(new SecretKeySpec(macKey, "HmacSHA384"));
                tLen = 24;
            } else if (Algorithm.A256CBC_HS512.equals(enc)) {
                mac = Mac.getInstance("HmacSHA512", "BC");
                mac.init(new SecretKeySpec(macKey, "HmacSHA512"));
                tLen = 32;
            } else {
                throw new IllegalStateException("Unsupported HMAC");
            }
            mac.update(jweAAD);
            mac.update(iv);
            mac.update(ciphertext);
            mac.update(al);
            byte[] thistag = mac.doFinal();
            boolean match = true;
            for (int i = tLen - 1; i >= 0; --i) {
                if (tag[i] != thistag[i]) {
                    match = false;
                }
            }
            if (!match) {
                throw new IllegalArgumentException("The message is invalid");
            }
            Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
            c.init(Cipher.DECRYPT_MODE, new SecretKeySpec(encKey, "AES"), new IvParameterSpec(iv));
            output = c.doFinal(ciphertext);
        } else if (Algorithm.A128GCM.equals(enc) || Algorithm.A192GCM.equals(enc)
                || Algorithm.A256GCM.equals(enc)) {
            Cipher c = Cipher.getInstance("AES/GCM/NoPadding", "BC");
            c.init(Cipher.DECRYPT_MODE, cek, new GCMParameterSpec(128, iv));
            c.updateAAD(jweAAD);
            byte[] block = new byte[ciphertext.length + tag.length];
            ByteBuffer buf = ByteBuffer.wrap(block);
            buf.put(ciphertext);
            buf.put(tag);
            try {
                output = c.doFinal(block);
            } catch (AEADBadTagException e) {
                throw new IllegalArgumentException("The message is invalid", e);
            }
        } else {
            throw new IllegalArgumentException("Unknown algorithm");
        }
    } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchProviderException | BadPaddingException
            | IllegalBlockSizeException | InvalidAlgorithmParameterException | NoSuchPaddingException e) {
        throw new RuntimeException(e);
    }

    // step 17
    if (zip != null) {
        if (Algorithm.DEFLATE.equals(zip)) {
            try {
                InflaterInputStream in = new InflaterInputStream(new ByteArrayInputStream(output));
                ByteArrayOutputStream out = new ByteArrayOutputStream(output.length * 2);
                int b;
                while ((b = in.read()) != -1) {
                    out.write(b);
                }
                out.flush();
                output = out.toByteArray();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            throw new IllegalArgumentException("Unknown compression");
        }
    }
    return output;
}