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());
}
}
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++;
}
}
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);
}
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;
}
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();
}
}
Aggregations