diff --git a/main/crypto-aes/pom.xml b/main/crypto-aes/pom.xml index c8a32706e..e9ebfa724 100644 --- a/main/crypto-aes/pom.xml +++ b/main/crypto-aes/pom.xml @@ -34,6 +34,13 @@ bcprov-jdk15on ${bouncycastle.version} + + + + org.cryptomator + siv-mode + 1.0.1 + diff --git a/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java b/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java index eb90a8c92..73c18c501 100644 --- a/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java +++ b/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java @@ -25,6 +25,7 @@ import java.util.Arrays; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import javax.crypto.AEADBadTagException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; @@ -45,6 +46,7 @@ import org.cryptomator.crypto.exceptions.MacAuthenticationFailedException; import org.cryptomator.crypto.exceptions.UnsupportedKeyLengthException; import org.cryptomator.crypto.exceptions.UnsupportedVaultException; import org.cryptomator.crypto.exceptions.WrongPasswordException; +import org.cryptomator.siv.SivMode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,6 +62,11 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration { */ private static final int AES_KEY_LENGTH_IN_BITS; + /** + * SIV mode for deterministic filename encryption. + */ + private static final SivMode AES_SIV = new SivMode(); + /** * PRNG for cryptographically secure random numbers. Defaults to SHA1-based number generator. * @@ -285,7 +292,7 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration { @Override public String encryptDirectoryPath(String cleartextDirectoryId, String nativePathSep) { final byte[] cleartextBytes = cleartextDirectoryId.getBytes(StandardCharsets.UTF_8); - byte[] encryptedBytes = AesSivCipherUtil.sivEncrypt(primaryMasterKey, hMacMasterKey, cleartextBytes); + byte[] encryptedBytes = AES_SIV.encrypt(primaryMasterKey, hMacMasterKey, cleartextBytes); final byte[] hashed = sha256().digest(encryptedBytes); final String encryptedThenHashedPath = ENCRYPTED_FILENAME_CODEC.encodeAsString(hashed); return encryptedThenHashedPath.substring(0, 2) + nativePathSep + encryptedThenHashedPath.substring(2); @@ -294,15 +301,19 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration { @Override public String encryptFilename(String cleartextName) { final byte[] cleartextBytes = cleartextName.getBytes(StandardCharsets.UTF_8); - final byte[] encryptedBytes = AesSivCipherUtil.sivEncrypt(primaryMasterKey, hMacMasterKey, cleartextBytes); + final byte[] encryptedBytes = AES_SIV.encrypt(primaryMasterKey, hMacMasterKey, cleartextBytes); return ENCRYPTED_FILENAME_CODEC.encodeAsString(encryptedBytes); } @Override public String decryptFilename(String ciphertextName) throws DecryptFailedException { final byte[] encryptedBytes = ENCRYPTED_FILENAME_CODEC.decode(ciphertextName); - final byte[] cleartextBytes = AesSivCipherUtil.sivDecrypt(primaryMasterKey, hMacMasterKey, encryptedBytes); - return new String(cleartextBytes, StandardCharsets.UTF_8); + try { + final byte[] cleartextBytes = AES_SIV.decrypt(primaryMasterKey, hMacMasterKey, encryptedBytes); + return new String(cleartextBytes, StandardCharsets.UTF_8); + } catch (AEADBadTagException e) { + throw new DecryptFailedException(e); + } } @Override diff --git a/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/AesSivCipherUtil.java b/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/AesSivCipherUtil.java deleted file mode 100644 index 023f28767..000000000 --- a/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/AesSivCipherUtil.java +++ /dev/null @@ -1,230 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Sebastian Stenzel - * This file is licensed under the terms of the MIT license. - * See the LICENSE.txt file for more info. - * - * Contributors: - * Sebastian Stenzel - initial API and implementation - ******************************************************************************/ -package org.cryptomator.crypto.aes256; - -import java.nio.ByteBuffer; -import java.security.InvalidKeyException; -import java.security.MessageDigest; -import java.util.Arrays; - -import javax.crypto.SecretKey; - -import org.apache.commons.lang3.ArrayUtils; -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.Mac; -import org.bouncycastle.crypto.engines.AESFastEngine; -import org.bouncycastle.crypto.macs.CMac; -import org.bouncycastle.crypto.paddings.ISO7816d4Padding; -import org.bouncycastle.crypto.params.KeyParameter; -import org.cryptomator.crypto.exceptions.DecryptFailedException; - -/** - * Implements the RFC 5297 SIV mode. - */ -final class AesSivCipherUtil { - - private static final byte[] BYTES_ZERO = new byte[16]; - private static final byte DOUBLING_CONST = (byte) 0x87; - - static byte[] sivEncrypt(SecretKey aesKey, SecretKey macKey, byte[] plaintext, byte[]... additionalData) { - final byte[] aesKeyBytes = aesKey.getEncoded(); - final byte[] macKeyBytes = macKey.getEncoded(); - if (aesKeyBytes == null || macKeyBytes == null) { - throw new IllegalArgumentException("Can't get bytes of given key."); - } - try { - return sivEncrypt(aesKeyBytes, macKeyBytes, plaintext, additionalData); - } catch (InvalidKeyException ex) { - throw new IllegalArgumentException(ex); - } finally { - Arrays.fill(aesKeyBytes, (byte) 0); - Arrays.fill(macKeyBytes, (byte) 0); - } - } - - static byte[] sivEncrypt(byte[] aesKey, byte[] macKey, byte[] plaintext, byte[]... additionalData) throws InvalidKeyException { - if (aesKey.length != 16 && aesKey.length != 24 && aesKey.length != 32) { - throw new InvalidKeyException("Invalid aesKey length " + aesKey.length); - } - - final byte[] iv = s2v(macKey, plaintext, additionalData); - - final int numBlocks = (plaintext.length + 15) / 16; - - // clear out the 31st and 63rd (rightmost) bit: - final byte[] ctr = Arrays.copyOf(iv, 16); - ctr[8] = (byte) (ctr[8] & 0x7F); - ctr[12] = (byte) (ctr[12] & 0x7F); - final ByteBuffer ctrBuf = ByteBuffer.wrap(ctr); - final long initialCtrVal = ctrBuf.getLong(8); - - final byte[] x = new byte[numBlocks * 16]; - final BlockCipher aes = new AESFastEngine(); - aes.init(true, new KeyParameter(aesKey)); - for (int i = 0; i < numBlocks; i++) { - final long ctrVal = initialCtrVal + i; - ctrBuf.putLong(8, ctrVal); - aes.processBlock(ctrBuf.array(), 0, x, i * 16); - aes.reset(); - } - - final byte[] ciphertext = xor(plaintext, x); - - return ArrayUtils.addAll(iv, ciphertext); - } - - static byte[] sivDecrypt(SecretKey aesKey, SecretKey macKey, byte[] plaintext, byte[]... additionalData) throws DecryptFailedException { - final byte[] aesKeyBytes = aesKey.getEncoded(); - final byte[] macKeyBytes = macKey.getEncoded(); - if (aesKeyBytes == null || macKeyBytes == null) { - throw new IllegalArgumentException("Can't get bytes of given key."); - } - try { - return sivDecrypt(aesKeyBytes, macKeyBytes, plaintext, additionalData); - } catch (InvalidKeyException ex) { - throw new IllegalArgumentException(ex); - } finally { - Arrays.fill(aesKeyBytes, (byte) 0); - Arrays.fill(macKeyBytes, (byte) 0); - } - } - - static byte[] sivDecrypt(byte[] aesKey, byte[] macKey, byte[] ciphertext, byte[]... additionalData) throws DecryptFailedException, InvalidKeyException { - if (aesKey.length != 16 && aesKey.length != 24 && aesKey.length != 32) { - throw new InvalidKeyException("Invalid aesKey length " + aesKey.length); - } - - final byte[] iv = Arrays.copyOf(ciphertext, 16); - - final byte[] actualCiphertext = Arrays.copyOfRange(ciphertext, 16, ciphertext.length); - final int numBlocks = (actualCiphertext.length + 15) / 16; - - // clear out the 31st and 63rd (rightmost) bit: - final byte[] ctr = Arrays.copyOf(iv, 16); - ctr[8] = (byte) (ctr[8] & 0x7F); - ctr[12] = (byte) (ctr[12] & 0x7F); - final ByteBuffer ctrBuf = ByteBuffer.wrap(ctr); - final long initialCtrVal = ctrBuf.getLong(8); - - final byte[] x = new byte[numBlocks * 16]; - final BlockCipher aes = new AESFastEngine(); - aes.init(true, new KeyParameter(aesKey)); - for (int i = 0; i < numBlocks; i++) { - final long ctrVal = initialCtrVal + i; - ctrBuf.putLong(8, ctrVal); - aes.processBlock(ctrBuf.array(), 0, x, i * 16); - aes.reset(); - } - - final byte[] plaintext = xor(actualCiphertext, x); - - final byte[] control = s2v(macKey, plaintext, additionalData); - - if (MessageDigest.isEqual(control, iv)) { - return plaintext; - } else { - throw new DecryptFailedException("Authentication failed"); - } - } - - static byte[] s2v(byte[] macKey, byte[] plaintext, byte[]... additionalData) { - final CipherParameters params = new KeyParameter(macKey); - final BlockCipher aes = new AESFastEngine(); - final CMac mac = new CMac(aes); - mac.init(params); - - byte[] d = mac(mac, BYTES_ZERO); - - for (byte[] s : additionalData) { - d = xor(dbl(d), mac(mac, s)); - } - - final byte[] t; - if (plaintext.length >= 16) { - t = xorend(plaintext, d); - } else { - t = xor(dbl(d), pad(plaintext)); - } - - return mac(mac, t); - } - - private static byte[] mac(Mac mac, byte[] in) { - byte[] result = new byte[mac.getMacSize()]; - mac.update(in, 0, in.length); - mac.doFinal(result, 0); - return result; - } - - /** - * First bit 1, following bits 0. - */ - private static byte[] pad(byte[] in) { - final byte[] result = Arrays.copyOf(in, 16); - new ISO7816d4Padding().addPadding(result, in.length); - return result; - } - - /** - * Code taken from {@link org.bouncycastle.crypto.macs.CMac} - */ - private static int shiftLeft(byte[] block, byte[] output) { - int i = block.length; - int bit = 0; - while (--i >= 0) { - int b = block[i] & 0xff; - output[i] = (byte) ((b << 1) | bit); - bit = (b >>> 7) & 1; - } - return bit; - } - - /** - * Code taken from {@link org.bouncycastle.crypto.macs.CMac} - */ - private static byte[] dbl(byte[] in) { - byte[] ret = new byte[in.length]; - int carry = shiftLeft(in, ret); - int xor = 0xff & DOUBLING_CONST; - - /* - * NOTE: This construction is an attempt at a constant-time implementation. - */ - ret[in.length - 1] ^= (xor >>> ((1 - carry) << 3)); - - return ret; - } - - private static byte[] xor(byte[] in1, byte[] in2) { - if (in1 == null || in2 == null || in1.length > in2.length) { - throw new IllegalArgumentException("Length of first input must be <= length of second input."); - } - - final byte[] result = new byte[in1.length]; - for (int i = 0; i < result.length; i++) { - result[i] = (byte) (in1[i] ^ in2[i]); - } - return result; - } - - private static byte[] xorend(byte[] in1, byte[] in2) { - if (in1 == null || in2 == null || in1.length < in2.length) { - throw new IllegalArgumentException("Length of first input must be >= length of second input."); - } - - final byte[] result = Arrays.copyOf(in1, in1.length); - final int diff = in1.length - in2.length; - for (int i = 0; i < in2.length; i++) { - result[i + diff] = (byte) (result[i + diff] ^ in2[i]); - } - return result; - } - -} diff --git a/main/crypto-aes/src/test/java/org/cryptomator/crypto/aes256/AesSivCipherUtilTest.java b/main/crypto-aes/src/test/java/org/cryptomator/crypto/aes256/AesSivCipherUtilTest.java deleted file mode 100644 index f263e2f85..000000000 --- a/main/crypto-aes/src/test/java/org/cryptomator/crypto/aes256/AesSivCipherUtilTest.java +++ /dev/null @@ -1,224 +0,0 @@ -package org.cryptomator.crypto.aes256; - -import java.security.InvalidKeyException; - -import org.apache.commons.codec.DecoderException; -import org.cryptomator.crypto.exceptions.DecryptFailedException; -import org.junit.Assert; -import org.junit.Test; - -/** - * Official RFC 5297 test vector taken from https://tools.ietf.org/html/rfc5297#appendix-A.1 - */ -public class AesSivCipherUtilTest { - - @Test - public void testS2v() throws DecoderException { - final byte[] macKey = {(byte) 0xff, (byte) 0xfe, (byte) 0xfd, (byte) 0xfc, // - (byte) 0xfb, (byte) 0xfa, (byte) 0xf9, (byte) 0xf8, // - (byte) 0xf7, (byte) 0xf6, (byte) 0xf5, (byte) 0xf4, // - (byte) 0xf3, (byte) 0xf2, (byte) 0xf1, (byte) 0xf0}; - - final byte[] ad = {(byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13, // - (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17, // - (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b, // - (byte) 0x1c, (byte) 0x1d, (byte) 0x1e, (byte) 0x1f, // - (byte) 0x20, (byte) 0x21, (byte) 0x22, (byte) 0x23, // - (byte) 0x24, (byte) 0x25, (byte) 0x26, (byte) 0x27}; - - final byte[] plaintext = {(byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, // - (byte) 0x55, (byte) 0x66, (byte) 0x77, (byte) 0x88, // - (byte) 0x99, (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, // - (byte) 0xdd, (byte) 0xee}; - - final byte[] expected = {(byte) 0x85, (byte) 0x63, (byte) 0x2d, (byte) 0x07, // - (byte) 0xc6, (byte) 0xe8, (byte) 0xf3, (byte) 0x7f, // - (byte) 0x95, (byte) 0x0a, (byte) 0xcd, (byte) 0x32, // - (byte) 0x0a, (byte) 0x2e, (byte) 0xcc, (byte) 0x93}; - - final byte[] result = AesSivCipherUtil.s2v(macKey, plaintext, ad); - Assert.assertArrayEquals(expected, result); - } - - @Test - public void testSivEncrypt() throws InvalidKeyException { - final byte[] macKey = {(byte) 0xff, (byte) 0xfe, (byte) 0xfd, (byte) 0xfc, // - (byte) 0xfb, (byte) 0xfa, (byte) 0xf9, (byte) 0xf8, // - (byte) 0xf7, (byte) 0xf6, (byte) 0xf5, (byte) 0xf4, // - (byte) 0xf3, (byte) 0xf2, (byte) 0xf1, (byte) 0xf0}; - - final byte[] aesKey = {(byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, // - (byte) 0xf4, (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, // - (byte) 0xf8, (byte) 0xf9, (byte) 0xfa, (byte) 0xfb, // - (byte) 0xfc, (byte) 0xfd, (byte) 0xfe, (byte) 0xff}; - - final byte[] ad = {(byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13, // - (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17, // - (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b, // - (byte) 0x1c, (byte) 0x1d, (byte) 0x1e, (byte) 0x1f, // - (byte) 0x20, (byte) 0x21, (byte) 0x22, (byte) 0x23, // - (byte) 0x24, (byte) 0x25, (byte) 0x26, (byte) 0x27}; - - final byte[] plaintext = {(byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, // - (byte) 0x55, (byte) 0x66, (byte) 0x77, (byte) 0x88, // - (byte) 0x99, (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, // - (byte) 0xdd, (byte) 0xee}; - - final byte[] expected = {(byte) 0x85, (byte) 0x63, (byte) 0x2d, (byte) 0x07, // - (byte) 0xc6, (byte) 0xe8, (byte) 0xf3, (byte) 0x7f, // - (byte) 0x95, (byte) 0x0a, (byte) 0xcd, (byte) 0x32, // - (byte) 0x0a, (byte) 0x2e, (byte) 0xcc, (byte) 0x93, // - (byte) 0x40, (byte) 0xc0, (byte) 0x2b, (byte) 0x96, // - (byte) 0x90, (byte) 0xc4, (byte) 0xdc, (byte) 0x04, // - (byte) 0xda, (byte) 0xef, (byte) 0x7f, (byte) 0x6a, // - (byte) 0xfe, (byte) 0x5c}; - - final byte[] result = AesSivCipherUtil.sivEncrypt(aesKey, macKey, plaintext, ad); - Assert.assertArrayEquals(expected, result); - } - - @Test - public void testSivDecrypt() throws DecryptFailedException, InvalidKeyException { - final byte[] macKey = {(byte) 0xff, (byte) 0xfe, (byte) 0xfd, (byte) 0xfc, // - (byte) 0xfb, (byte) 0xfa, (byte) 0xf9, (byte) 0xf8, // - (byte) 0xf7, (byte) 0xf6, (byte) 0xf5, (byte) 0xf4, // - (byte) 0xf3, (byte) 0xf2, (byte) 0xf1, (byte) 0xf0}; - - final byte[] aesKey = {(byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, // - (byte) 0xf4, (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, // - (byte) 0xf8, (byte) 0xf9, (byte) 0xfa, (byte) 0xfb, // - (byte) 0xfc, (byte) 0xfd, (byte) 0xfe, (byte) 0xff}; - - final byte[] ad = {(byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13, // - (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17, // - (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b, // - (byte) 0x1c, (byte) 0x1d, (byte) 0x1e, (byte) 0x1f, // - (byte) 0x20, (byte) 0x21, (byte) 0x22, (byte) 0x23, // - (byte) 0x24, (byte) 0x25, (byte) 0x26, (byte) 0x27}; - - final byte[] ciphertext = {(byte) 0x85, (byte) 0x63, (byte) 0x2d, (byte) 0x07, // - (byte) 0xc6, (byte) 0xe8, (byte) 0xf3, (byte) 0x7f, // - (byte) 0x95, (byte) 0x0a, (byte) 0xcd, (byte) 0x32, // - (byte) 0x0a, (byte) 0x2e, (byte) 0xcc, (byte) 0x93, // - (byte) 0x40, (byte) 0xc0, (byte) 0x2b, (byte) 0x96, // - (byte) 0x90, (byte) 0xc4, (byte) 0xdc, (byte) 0x04, // - (byte) 0xda, (byte) 0xef, (byte) 0x7f, (byte) 0x6a, // - (byte) 0xfe, (byte) 0x5c}; - - final byte[] expected = {(byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, // - (byte) 0x55, (byte) 0x66, (byte) 0x77, (byte) 0x88, // - (byte) 0x99, (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, // - (byte) 0xdd, (byte) 0xee}; - - final byte[] result = AesSivCipherUtil.sivDecrypt(aesKey, macKey, ciphertext, ad); - Assert.assertArrayEquals(expected, result); - } - - @Test(expected = DecryptFailedException.class) - public void testSivDecryptWithInvalidKey() throws DecryptFailedException, InvalidKeyException { - final byte[] macKey = {(byte) 0xff, (byte) 0xfe, (byte) 0xfd, (byte) 0xfc, // - (byte) 0xfb, (byte) 0xfa, (byte) 0xf9, (byte) 0xf8, // - (byte) 0xf7, (byte) 0xf6, (byte) 0xf5, (byte) 0xf4, // - (byte) 0xf3, (byte) 0xf2, (byte) 0xf1, (byte) 0xf0}; - - final byte[] aesKey = {(byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, // - (byte) 0xf4, (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, // - (byte) 0xf8, (byte) 0xf9, (byte) 0xfa, (byte) 0xfb, // - (byte) 0xfc, (byte) 0xfd, (byte) 0xfe, (byte) 0x00}; - - final byte[] ad = {(byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13, // - (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17, // - (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b, // - (byte) 0x1c, (byte) 0x1d, (byte) 0x1e, (byte) 0x1f, // - (byte) 0x20, (byte) 0x21, (byte) 0x22, (byte) 0x23, // - (byte) 0x24, (byte) 0x25, (byte) 0x26, (byte) 0x27}; - - final byte[] ciphertext = {(byte) 0x85, (byte) 0x63, (byte) 0x2d, (byte) 0x07, // - (byte) 0xc6, (byte) 0xe8, (byte) 0xf3, (byte) 0x7f, // - (byte) 0x95, (byte) 0x0a, (byte) 0xcd, (byte) 0x32, // - (byte) 0x0a, (byte) 0x2e, (byte) 0xcc, (byte) 0x93, // - (byte) 0x40, (byte) 0xc0, (byte) 0x2b, (byte) 0x96, // - (byte) 0x90, (byte) 0xc4, (byte) 0xdc, (byte) 0x04, // - (byte) 0xda, (byte) 0xef, (byte) 0x7f, (byte) 0x6a, // - (byte) 0xfe, (byte) 0x5c}; - - final byte[] expected = {(byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, // - (byte) 0x55, (byte) 0x66, (byte) 0x77, (byte) 0x88, // - (byte) 0x99, (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, // - (byte) 0xdd, (byte) 0xee}; - - final byte[] result = AesSivCipherUtil.sivDecrypt(aesKey, macKey, ciphertext, ad); - Assert.assertArrayEquals(expected, result); - } - - /** - * https://tools.ietf.org/html/rfc5297#appendix-A.2 - */ - @Test - public void testNonceBasedAuthenticatedEncryption() throws InvalidKeyException { - final byte[] macKey = {(byte) 0x7f, (byte) 0x7e, (byte) 0x7d, (byte) 0x7c, // - (byte) 0x7b, (byte) 0x7a, (byte) 0x79, (byte) 0x78, // - (byte) 0x77, (byte) 0x76, (byte) 0x75, (byte) 0x74, // - (byte) 0x73, (byte) 0x72, (byte) 0x71, (byte) 0x70}; - - final byte[] aesKey = {(byte) 0x40, (byte) 0x41, (byte) 0x42, (byte) 0x43, // - (byte) 0x44, (byte) 0x45, (byte) 0x46, (byte) 0x47, // - (byte) 0x48, (byte) 0x49, (byte) 0x4a, (byte) 0x4b, // - (byte) 0x4c, (byte) 0x4d, (byte) 0x4e, (byte) 0x4f}; - - final byte[] ad1 = {(byte) 0x00, (byte) 0x11, (byte) 0x22, (byte) 0x33, // - (byte) 0x44, (byte) 0x55, (byte) 0x66, (byte) 0x77, // - (byte) 0x88, (byte) 0x99, (byte) 0xaa, (byte) 0xbb, // - (byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, // - (byte) 0xde, (byte) 0xad, (byte) 0xda, (byte) 0xda, // - (byte) 0xde, (byte) 0xad, (byte) 0xda, (byte) 0xda, // - (byte) 0xff, (byte) 0xee, (byte) 0xdd, (byte) 0xcc, // - (byte) 0xbb, (byte) 0xaa, (byte) 0x99, (byte) 0x88, // - (byte) 0x77, (byte) 0x66, (byte) 0x55, (byte) 0x44, // - (byte) 0x33, (byte) 0x22, (byte) 0x11, (byte) 0x00}; - - final byte[] ad2 = {(byte) 0x10, (byte) 0x20, (byte) 0x30, (byte) 0x40, // - (byte) 0x50, (byte) 0x60, (byte) 0x70, (byte) 0x80, // - (byte) 0x90, (byte) 0xa0}; - - final byte[] nonce = {(byte) 0x09, (byte) 0xf9, (byte) 0x11, (byte) 0x02, // - (byte) 0x9d, (byte) 0x74, (byte) 0xe3, (byte) 0x5b, // - (byte) 0xd8, (byte) 0x41, (byte) 0x56, (byte) 0xc5, // - (byte) 0x63, (byte) 0x56, (byte) 0x88, (byte) 0xc0}; - - final byte[] plaintext = {(byte) 0x74, (byte) 0x68, (byte) 0x69, (byte) 0x73, // - (byte) 0x20, (byte) 0x69, (byte) 0x73, (byte) 0x20, // - (byte) 0x73, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, // - (byte) 0x20, (byte) 0x70, (byte) 0x6c, (byte) 0x61, // - (byte) 0x69, (byte) 0x6e, (byte) 0x74, (byte) 0x65, // - (byte) 0x78, (byte) 0x74, (byte) 0x20, (byte) 0x74, // - (byte) 0x6f, (byte) 0x20, (byte) 0x65, (byte) 0x6e, // - (byte) 0x63, (byte) 0x72, (byte) 0x79, (byte) 0x70, // - (byte) 0x74, (byte) 0x20, (byte) 0x75, (byte) 0x73, // - (byte) 0x69, (byte) 0x6e, (byte) 0x67, (byte) 0x20, // - (byte) 0x53, (byte) 0x49, (byte) 0x56, (byte) 0x2d, // - (byte) 0x41, (byte) 0x45, (byte) 0x53}; - - final byte[] result = AesSivCipherUtil.sivEncrypt(aesKey, macKey, plaintext, ad1, ad2, nonce); - - final byte[] expected = {(byte) 0x7b, (byte) 0xdb, (byte) 0x6e, (byte) 0x3b, // - (byte) 0x43, (byte) 0x26, (byte) 0x67, (byte) 0xeb, // - (byte) 0x06, (byte) 0xf4, (byte) 0xd1, (byte) 0x4b, // - (byte) 0xff, (byte) 0x2f, (byte) 0xbd, (byte) 0x0f, // - (byte) 0xcb, (byte) 0x90, (byte) 0x0f, (byte) 0x2f, // - (byte) 0xdd, (byte) 0xbe, (byte) 0x40, (byte) 0x43, // - (byte) 0x26, (byte) 0x60, (byte) 0x19, (byte) 0x65, // - (byte) 0xc8, (byte) 0x89, (byte) 0xbf, (byte) 0x17, // - (byte) 0xdb, (byte) 0xa7, (byte) 0x7c, (byte) 0xeb, // - (byte) 0x09, (byte) 0x4f, (byte) 0xa6, (byte) 0x63, // - (byte) 0xb7, (byte) 0xa3, (byte) 0xf7, (byte) 0x48, // - (byte) 0xba, (byte) 0x8a, (byte) 0xf8, (byte) 0x29, // - (byte) 0xea, (byte) 0x64, (byte) 0xad, (byte) 0x54, // - (byte) 0x4a, (byte) 0x27, (byte) 0x2e, (byte) 0x9c, // - (byte) 0x48, (byte) 0x5b, (byte) 0x62, (byte) 0xa3, // - (byte) 0xfd, (byte) 0x5c, (byte) 0x0d}; - - Assert.assertArrayEquals(expected, result); - - } -} diff --git a/main/pom.xml b/main/pom.xml index 83fd0408d..9b64b48fd 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -43,6 +43,13 @@ 2.4.4 1.10.19 + + + + jitpack.io + https://jitpack.io + +