Привет, Хабр! Представляю вашему вниманию перевод четвертой статьи "Java Mac" автора Jakob Jenkov из серии статей для начинающих, желающих освоить основы криптографии в Java.
Оглавление:
- Java Cryptography
- Java Cipher
- MessageDigest
- Mac
- Signature
- KeyPair
- KeyGenerator
- KeyPairGenerator
- KeyStore
- Keytool
- Certificate
- CertificateFactory
- CertPath
Message Authentication Code (MAC) (Код аутентификации сообщения или имитовставка)
Java Mac (javax.crypto.Mac) создает код аутентификации сообщений (MAC) из двоичных данных. MAC — это дайджест сообщения, зашифрованный секретным ключом. Только при наличии секретного ключа вы сможете проверить подлинность MAC.
Создание экземпляра
Прежде чем использовать класс Mac, необходимо создать экземпляр Mac. Создание экземпляра класса Mac выполняется с помощью метода getInstance(). Вот пример создания экземпляра Mac:
Mac mac = Mac.getInstance("HmacSHA256");
Строковый параметр, передаваемый методу getInstance(), содержит имя используемого алгоритма. В этом случае используется алгоритм HmacSHA256.
Инициализация
После создания экземпляра, Mac должен быть инициализирован. Экземпляр Mac инициализируется вызывом метода init(), передавая в качестве параметра секретный ключ, который будет использоваться экземпляром. Вот пример инициализации экземпляра Mac:
byte[] keyBytes = new byte[]{0,1,2,3,4,5,6,7,8 ,9,10,11,12,13,14,15};
String algorithm = "RawBytes";
SecretKeySpec key = new SecretKeySpec(keyBytes, algorithm);
mac.init(key);
Метод init() принимает экземпляр Key. В этом примере используется SecretKeySpec, который реализует интерфейс Key.
Вычисление MAC
При помощи экземпляра MAC(после инициализации) можно начать вычислять MAC данных. Чтобы вычислить значение MAC, вы вызываете метод update() или doFinal(). Если у вас есть только один блок данных для вычисления MAC, вы можете напрямую вызвать doFinal(), например:
byte[] data = "abcdefghijklmnopqrstuvxyz".getBytes("UTF-8");
byte[] macBytes = mac.doFinal(data);
Если у вас есть несколько блоков данных для расчета MAC, например, если вы читаете файл блок за блоком, то вы должны вызывать метод update() для каждого блока и заканчивать вызовом doFinal() на последнем блоке. Вот пример:
byte[] data = "abcdefghijklmnopqrstuvxyz".getBytes("UTF-8");
byte[] data2 = "0123456789".getBytes("UTF-8");
mac.update(data);
mac.update(data2);
byte[] macBytes = mac.doFinal();