iOS CryptoKit AES-GCM можно ли использовать одноразовый номер менее 12 байт?

Я пытаюсь взаимодействовать с существующим устройством, которое использует AES-GCM с 4-байтовым одноразовым номером (UInt32). Это простой инкрементный счетчик, который увеличивается каждый раз при выполнении операции:

var cryptoCounter: UInt32 = 0

Затем я пытаюсь зашифровать его и получить следующие значения:

let key = SymmetricKey(data: sharedKey) // This is a 32-byte key.
let nonceData = withUnsafeBytes(of: cryptoCounter.bigEndian, Array.init) // Convert UInt32 to 4-byte data.
let nonce = try! AES.GCM.Nonce(data: Data(nonceData)) // This throws an invalid parameter size exception.
let encrypted = try! AES.GCM.seal(serialized, using: key, nonce: nonce)

Тем не менее AES.GCM.Nonceне работает с менее чем 12 байтами, поэтому 4-байтовый одноразовый номер вызывает ошибку. Я пробовал заполнить одноразовый номер запасными 8-байтами 0:

let nonceData = [0, 0, 0, 0, 0, 0, 0, 0] + withUnsafeBytes(of: cryptoCounter.bigEndian, Array.init)

Но зашифрованное значение отклоняется устройством, поэтому я предполагаю, что это неверно. Если у кого-нибудь есть предложения по лучшему способу реализации этого Swift, это было бы замечательно! Спасибо.

1 ответ

Решение

Я нашел решение, которое сработало для меня.

Я использовал отличную библиотеку CryptoSwift (7,8 тыс. Звезд на GitHub на момент написания):

let gcm = GCM(iv: withUnsafeBytes(of: cryptoCounter.bigEndian, Array.init), mode: .detached)
let aes = try! AES(key: [UInt8](sharedKey), blockMode: gcm, padding: .noPadding)
let encrypted = try! aes.encrypt([UInt8](serialized))
Другие вопросы по тегам