oss-sec mailing list archives
Re: Default IV & other issues in aes-js & pyaes modules, & strongMan VPN manager
From: Soatok Dreamseeker <soatok.dhole () gmail com>
Date: Thu, 19 Feb 2026 13:35:10 -0500
Hi Alan, On Thu, Feb 19, 2026 at 1:27 PM Alan Coopersmith <alan.coopersmith () oracle com> wrote:
https://blog.trailofbits.com/2026/02/18/carelessness-versus-craftsmanship-in-cryptography/ reports:Two popular AES libraries, aes-js and pyaes, “helpfully” provide a default IV in their AES-CTR API, leading to a large number of key/IV reuse bugs. These bugs potentially affect thousands of downstream projects.
strongMan is a web-based management tool for folks using the strongSwan VPN suite. It allows for credential and user management, initiation of VPN connections, and more. It’s a pretty slick piece of software; if you’re into IPsec VPNs, you should definitely give it a look.
There will be a security advisory for strongMan issued in conjunction with this fix, outlining the nature of the problem, its severity, and the measures taken to address it. Everything will be out in the open, with full transparency for all strongMan users.
That strongMan patch is refreshing to see: The latest version fixes the issue by switching to AES-GCM-SIV encryption
with a random nonce and an individually derived encryption key, using HKDF, for each encrypted value. Database migrations are provided to automatically re-encrypt all credentials.
The patch is also pretty small: diff --git a/requirements.txt b/requirements.txt index 6cf1caa..111fa76 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ Django==4.2.28 git+https://github.com/wbond/oscrypto.git@1547f535001ba568b239b8797465536759c742a3 asn1crypto==1.5.1 +cryptography==46.0.3 pyaes==1.6.1 django-tables2==2.3.4 vici==5.8.4 diff --git a/strongMan/helper_apps/encryption/fields.py b/strongMan/helper_apps/encryption/fields.py index f574782..3af11eb 100644 --- a/strongMan/helper_apps/encryption/fields.py +++ b/strongMan/helper_apps/encryption/fields.py @@ -1,11 +1,16 @@ ''' https://github.com/orcasgit/django-fernet-fields ''' +import os + from django.conf import settings from django.core.exceptions import FieldError, ImproperlyConfigured from django.db import models from django.utils.encoding import force_bytes, force_str from django.utils.functional import cached_property +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.ciphers.aead import AESGCMSIV +from cryptography.hazmat.primitives.kdf.hkdf import HKDF from pyaes import aes as aeslib __all__ = [ @@ -20,7 +25,7 @@ class EncryptedField(models.Field): - """A field that encrypts values using Fernet symmetric encryption.""" + """A field that encrypts values using AES-GCM-SIV symmetric encryption.""" _internal_type = 'BinaryField' def __init__(self, *args, **kwargs): @@ -42,12 +47,24 @@ def __init__(self, *args, **kwargs): super(EncryptedField, self).__init__(*args, **kwargs) def encrypt(self, value): - aes = aeslib.AESModeOfOperationCTR(self.key) - return aes.encrypt(value) + # we use a random nonce for the encryption and to generate an individual encryption key, which is + # then concatenated and separated by a : from the ciphertext + nonce = os.urandom(12) + # leave the salt intentionally blank + hkdf = HKDF(algorithm=hashes.SHA256(), length=32, salt=b'', info=nonce + b'EncryptedField') + aesgcmsiv = AESGCMSIV(hkdf.derive(self.key)) + return nonce + b':' + aesgcmsiv.encrypt(nonce, value, None) def decrypt(self, value): - aes = aeslib.AESModeOfOperationCTR(self.key) - return aes.decrypt(value) + # decrypt unsafe legacy values if we don't find a nonce + if len(value) < 13 or value[12] != b':'[0]: + aes = aeslib.AESModeOfOperationCTR(self.key) + return aes.decrypt(value) + # <12-byte nonce>:<ciphertext> + nonce = value[:12] + hkdf = HKDF(algorithm=hashes.SHA256(), length=32, salt=b'', info=nonce + b'EncryptedField') + aesgcmsiv = AESGCMSIV(hkdf.derive(self.key)) + return aesgcmsiv.decrypt(nonce, value[13:], None) @cached_property def key(self): Hell, it even uses HKDF correctly <https://soatok.blog/2021/11/17/understanding-hkdf/>. Most people screw HKDF up in a way that only security proof authors really care about, and they didn't. Just wanted to say: As awful as pyaes and aes-js are, seeing this high quality work in response to the disclosure is a little heartwarming.
Current thread:
- Default IV & other issues in aes-js & pyaes modules, & strongMan VPN manager Alan Coopersmith (Feb 19)
- Re: Default IV & other issues in aes-js & pyaes modules, & strongMan VPN manager Soatok Dreamseeker (Feb 19)
