Search in sources :

Example 36 with InvalidCipherTextException

use of org.bouncycastle.crypto.InvalidCipherTextException in project openremote by openremote.

the class NetworkLayer method parseControlMessage.

/**
 * Parses control message
 *
 * @param key                     Network Key used to decrypt
 * @param provisionerAddress      Provisioner address.
 * @param data                    Data received from the node.
 * @param networkHeader           De-obfuscated network header.
 * @param decryptedNetworkPayload Decrypted network payload.
 * @param src                     Source address where the pdu originated from.
 * @param sequenceNumber          Sequence number of the received message.
 * @return a complete {@link ControlMessage} or null if the message was unable to parsed
 */
private ControlMessage parseControlMessage(final NetworkKey key, /* @Nullable */
final Integer provisionerAddress, final byte[] data, final byte[] networkHeader, final byte[] decryptedNetworkPayload, final int src, final byte[] sequenceNumber) throws ExtendedInvalidCipherTextException {
    try {
        final int ttl = networkHeader[0] & 0x7F;
        final int dst = MeshParserUtils.unsignedBytesToInt(decryptedNetworkPayload[1], decryptedNetworkPayload[0]);
        // Removing the mDst here
        final byte[] decryptedProxyPdu = ByteBuffer.allocate(2 + networkHeader.length + decryptedNetworkPayload.length).order(ByteOrder.BIG_ENDIAN).put(data, 0, 2).put(networkHeader).put(decryptedNetworkPayload).array();
        // We check the pdu type
        final int pduType = data[0];
        switch(pduType) {
            case MeshManagerApi.PDU_TYPE_NETWORK:
                // This is not possible however let's return null
                if (provisionerAddress == null) {
                    return null;
                }
                // Check if the message is directed to us, if its not ignore the message
                if (provisionerAddress != dst) {
                    LOG.info("Received a control message that was not directed to us, so we drop it");
                    return null;
                }
                if (isSegmentedMessage(decryptedNetworkPayload[2])) {
                    return parseSegmentedControlMessage(key, data, decryptedProxyPdu, ttl, src, dst);
                } else {
                    return parseUnsegmentedControlMessage(key, data, decryptedProxyPdu, ttl, src, dst, sequenceNumber);
                }
            case MeshManagerApi.PDU_TYPE_PROXY_CONFIGURATION:
                // Proxy configuration messages are segmented only at the gatt level
                return parseUnsegmentedControlMessage(key, data, decryptedProxyPdu, ttl, src, dst, sequenceNumber);
            default:
                return null;
        }
    } catch (InvalidCipherTextException ex) {
        throw new ExtendedInvalidCipherTextException(ex.getMessage(), ex.getCause(), NetworkLayer.class.getSimpleName());
    }
}
Also used : InvalidCipherTextException(org.bouncycastle.crypto.InvalidCipherTextException) ExtendedInvalidCipherTextException(org.openremote.agent.protocol.bluetooth.mesh.utils.ExtendedInvalidCipherTextException) ExtendedInvalidCipherTextException(org.openremote.agent.protocol.bluetooth.mesh.utils.ExtendedInvalidCipherTextException)

Example 37 with InvalidCipherTextException

use of org.bouncycastle.crypto.InvalidCipherTextException in project openremote by openremote.

the class BaseMeshMessageHandler method parseMeshPduNotifications.

/**
 * Parse the mesh network/proxy pdus
 * <p>
 * This method will try to network layer de-obfuscation and decryption using the available network keys
 * </p>
 *
 * @param pdu     mesh pdu that was sent
 * @param network {@link MeshNetwork}
 */
protected synchronized void parseMeshPduNotifications(final byte[] pdu, final MeshNetwork network) throws ExtendedInvalidCipherTextException {
    final List<NetworkKey> networkKeys = network.getNetKeys();
    final int ivi = ((pdu[1] & 0xFF) >>> 7) & 0x01;
    final int nid = pdu[1] & 0x7F;
    final int acceptedIvIndex = network.getIvIndex().getIvIndex();
    int ivIndex = acceptedIvIndex == 0 ? 0 : acceptedIvIndex - 1;
    int tempIvIndex = ivIndex;
    NetworkKey networkKey = null;
    SecureUtils.K2Output k2Output = null;
    byte[] networkHeader = null;
    int ctlTtl = 0;
    int ctl = 0;
    int src = 0;
    ProvisionedMeshNode node = null;
    while (tempIvIndex <= ivIndex + 1) {
        // Here we go through all the network keys and filter out network keys based on the nid.
        for (int i = 0; i < networkKeys.size(); i++) {
            networkKey = networkKeys.get(i);
            k2Output = getMatchingK2Output(networkKey, nid);
            if (k2Output != null) {
                networkHeader = deObfuscateNetworkHeader(pdu, MeshParserUtils.intToBytes(tempIvIndex), k2Output.getPrivacyKey());
                ctlTtl = networkHeader[0];
                ctl = (ctlTtl >> 7) & 0x01;
                src = MeshParserUtils.unsignedBytesToInt(networkHeader[5], networkHeader[4]);
                // Check if the src is known to the network and if found let's break
                // Note a node may not be found if there are two provisioners are operating independently without syncing the network.
                node = network.getNode(src);
                if (node != null) {
                    break;
                }
            }
        }
        // IF the node was found we can safely try to decrypt message with the network key which we found src of the message.
        if (node != null && k2Output != null) {
            final byte[] sequenceNumber = ByteBuffer.allocate(3).order(ByteOrder.BIG_ENDIAN).put(networkHeader, 1, 3).array();
            LOG.info("Sequence number of received Network PDU: " + MeshParserUtils.convert24BitsToInt(sequenceNumber));
            // TODO validate ivi
            byte[] nonce;
            try {
                final int networkPayloadLength = pdu.length - (2 + networkHeader.length);
                final byte[] transportPdu = new byte[networkPayloadLength];
                System.arraycopy(pdu, 8, transportPdu, 0, networkPayloadLength);
                final byte[] decryptedPayload;
                final MeshMessageState state;
                if (pdu[0] == MeshManagerApi.PDU_TYPE_NETWORK) {
                    nonce = createNetworkNonce((byte) ctlTtl, sequenceNumber, src, MeshParserUtils.intToBytes(tempIvIndex));
                    decryptedPayload = SecureUtils.decryptCCM(transportPdu, k2Output.getEncryptionKey(), nonce, SecureUtils.getNetMicLength(ctl));
                    state = getState(src);
                } else {
                    nonce = createProxyNonce(sequenceNumber, src, MeshParserUtils.intToBytes(tempIvIndex));
                    decryptedPayload = SecureUtils.decryptCCM(transportPdu, k2Output.getEncryptionKey(), nonce, SecureUtils.getNetMicLength(ctl));
                    state = getState(MeshAddress.UNASSIGNED_ADDRESS);
                }
                if (state != null) {
                    // TODO look in to proxy filter messages
                    ((DefaultNoOperationMessageState) state).parseMeshPdu(networkKey, node, pdu, networkHeader, decryptedPayload, tempIvIndex, sequenceNumber);
                    return;
                }
            } catch (InvalidCipherTextException ex) {
                throw new ExtendedInvalidCipherTextException(ex.getMessage(), ex.getCause(), BaseMeshMessageHandler.class.getName());
            }
        }
        tempIvIndex++;
    }
}
Also used : NetworkKey(org.openremote.agent.protocol.bluetooth.mesh.NetworkKey) InvalidCipherTextException(org.bouncycastle.crypto.InvalidCipherTextException) ExtendedInvalidCipherTextException(org.openremote.agent.protocol.bluetooth.mesh.utils.ExtendedInvalidCipherTextException) ExtendedInvalidCipherTextException(org.openremote.agent.protocol.bluetooth.mesh.utils.ExtendedInvalidCipherTextException) SecureUtils(org.openremote.agent.protocol.bluetooth.mesh.utils.SecureUtils)

Example 38 with InvalidCipherTextException

use of org.bouncycastle.crypto.InvalidCipherTextException in project nem2-sdk-java by nemtech.

the class AESGCM method encrypt.

/**
 * Encrypts the specified plain text using AES/GCM/NoPadding.
 *
 * @param secretKey The AES key. Must not be {@code null}.
 * @param plainText The plain text. Must not be {@code null}.
 * @param iv The initialisation vector (IV). Must not be {@code null}.
 * @return The authenticated cipher text.
 * @throws CryptoException If encryption failed.
 */
public static AuthenticatedCipherText encrypt(final byte[] secretKey, final byte[] iv, final byte[] plainText) throws RuntimeException {
    // Initialise AES/GCM cipher for encryption
    GCMBlockCipher cipher = createAESGCMCipher(secretKey, true, iv);
    // Prepare output buffer
    int outputLength = cipher.getOutputSize(plainText.length);
    byte[] output = new byte[outputLength];
    // Produce cipher text
    int outputOffset = cipher.processBytes(plainText, 0, plainText.length, output, 0);
    // Produce authentication tag
    try {
        outputOffset += cipher.doFinal(output, outputOffset);
    } catch (InvalidCipherTextException e) {
        throw new CryptoException("Could Not Generate GCM Authentication: " + ExceptionUtils.getMessage(e), e);
    }
    // Split output into cipher text and authentication tag
    int authTagLength = AUTH_TAG_BIT_LENGTH / 8;
    byte[] cipherText = new byte[outputOffset - authTagLength];
    byte[] authTag = new byte[authTagLength];
    System.arraycopy(output, 0, cipherText, 0, cipherText.length);
    System.arraycopy(output, outputOffset - authTagLength, authTag, 0, authTag.length);
    return new AuthenticatedCipherText(cipherText, authTag, iv);
}
Also used : InvalidCipherTextException(org.bouncycastle.crypto.InvalidCipherTextException) CryptoException(io.nem.symbol.core.crypto.CryptoException) GCMBlockCipher(org.bouncycastle.crypto.modes.GCMBlockCipher)

Example 39 with InvalidCipherTextException

use of org.bouncycastle.crypto.InvalidCipherTextException in project nem2-sdk-java by nemtech.

the class AESGCM method decrypt.

/**
 * Decrypts the specified cipher text using AES/GCM/NoPadding.
 *
 * @param secretKey The AES key. Must not be {@code null}.
 * @param iv The initialisation vector (IV). Must not be {@code null}.
 * @param cipherText The cipher text. Must not be {@code null}.
 * @param authTag The authentication tag. Must not be {@code null}.
 * @return The decrypted plain text.
 * @throws CryptoException If decryption failed.
 */
public static byte[] decrypt(final byte[] secretKey, final byte[] iv, final byte[] cipherText, final byte[] authTag) throws RuntimeException {
    // Initialise AES/GCM cipher for decryption
    GCMBlockCipher cipher = createAESGCMCipher(secretKey, false, iv);
    // Join cipher text and authentication tag to produce cipher input
    byte[] input = new byte[cipherText.length + authTag.length];
    System.arraycopy(cipherText, 0, input, 0, cipherText.length);
    System.arraycopy(authTag, 0, input, cipherText.length, authTag.length);
    int outputLength = cipher.getOutputSize(input.length);
    byte[] output = new byte[outputLength];
    // Decrypt
    int outputOffset = cipher.processBytes(input, 0, input.length, output, 0);
    // Validate authentication tag
    try {
        outputOffset += cipher.doFinal(output, outputOffset);
    } catch (InvalidCipherTextException e) {
        throw new CryptoException("Could decrypt value: " + ExceptionUtils.getMessage(e), e);
    }
    return output;
}
Also used : InvalidCipherTextException(org.bouncycastle.crypto.InvalidCipherTextException) CryptoException(io.nem.symbol.core.crypto.CryptoException) GCMBlockCipher(org.bouncycastle.crypto.modes.GCMBlockCipher)

Example 40 with InvalidCipherTextException

use of org.bouncycastle.crypto.InvalidCipherTextException in project hutool by looly.

the class SM2 method encrypt.

/**
 * 加密,SM2非对称加密的结果由C1,C2,C3三部分组成,其中:
 *
 * <pre>
 * C1 生成随机数的计算出的椭圆曲线点
 * C2 密文数据
 * C3 SM3的摘要值
 * </pre>
 *
 * @param data             被加密的bytes
 * @param pubKeyParameters 公钥参数
 * @return 加密后的bytes
 * @throws CryptoException 包括InvalidKeyException和InvalidCipherTextException的包装异常
 * @since 5.1.6
 */
public byte[] encrypt(byte[] data, CipherParameters pubKeyParameters) throws CryptoException {
    lock.lock();
    final SM2Engine engine = getEngine();
    try {
        engine.init(true, pubKeyParameters);
        return engine.processBlock(data, 0, data.length);
    } catch (InvalidCipherTextException e) {
        throw new CryptoException(e);
    } finally {
        lock.unlock();
    }
}
Also used : InvalidCipherTextException(org.bouncycastle.crypto.InvalidCipherTextException) SM2Engine(org.bouncycastle.crypto.engines.SM2Engine) CryptoException(cn.hutool.crypto.CryptoException)

Aggregations

InvalidCipherTextException (org.bouncycastle.crypto.InvalidCipherTextException)46 KeyParameter (org.bouncycastle.crypto.params.KeyParameter)13 ParametersWithIV (org.bouncycastle.crypto.params.ParametersWithIV)13 AESEngine (org.bouncycastle.crypto.engines.AESEngine)12 CipherParameters (org.bouncycastle.crypto.CipherParameters)11 PaddedBufferedBlockCipher (org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher)9 IOException (java.io.IOException)7 DataLengthException (org.bouncycastle.crypto.DataLengthException)7 CBCBlockCipher (org.bouncycastle.crypto.modes.CBCBlockCipher)7 GCMBlockCipher (org.bouncycastle.crypto.modes.GCMBlockCipher)7 GoCipher (com.thoughtworks.go.security.GoCipher)6 Test (org.junit.Test)6 BadPaddingException (javax.crypto.BadPaddingException)5 BlockCipher (org.bouncycastle.crypto.BlockCipher)5 BufferedBlockCipher (org.bouncycastle.crypto.BufferedBlockCipher)5 UrlArgument (com.thoughtworks.go.util.command.UrlArgument)4 UnsupportedEncodingException (java.io.UnsupportedEncodingException)4 ExtendedInvalidCipherTextException (org.openremote.agent.protocol.bluetooth.mesh.utils.ExtendedInvalidCipherTextException)4 IllegalBlockSizeException (javax.crypto.IllegalBlockSizeException)3 SecretKeySpec (javax.crypto.spec.SecretKeySpec)3