Modify rule S4426: Add how to fix it for cryptodome and pyOpenSSL and close gap with NIST (#3678)
This commit is contained in:
parent
6aed7888c4
commit
0006c98874
@ -73,34 +73,35 @@
|
||||
* WordPress
|
||||
* Mcrypt
|
||||
// Python
|
||||
* aiohttp
|
||||
* Amazon DynamoDB
|
||||
* Amazon DynamoDB
|
||||
* Cryptodome
|
||||
* Django
|
||||
* Django Templates
|
||||
* Flask
|
||||
* aiohttp
|
||||
* FastAPI
|
||||
* FastAPI
|
||||
* Flask
|
||||
* HTTPX
|
||||
* Jinja
|
||||
* lxml
|
||||
* Paramiko
|
||||
* python-ldap
|
||||
* Python SQLite
|
||||
* MySQL Connector/Python
|
||||
* Python Standard Library
|
||||
* PyYAML
|
||||
* Requests
|
||||
* HTTPX
|
||||
* SQLAlchemy
|
||||
* Amazon DynamoDB
|
||||
* python-ldap
|
||||
* Request
|
||||
* Cryptodome
|
||||
* Paramiko
|
||||
* pyca
|
||||
* PyCrypto
|
||||
* pyDes
|
||||
* PyJWT
|
||||
* python-jwt
|
||||
* FastAPI
|
||||
* pyOpenSSL
|
||||
* python-jose
|
||||
* python-jwt
|
||||
* python-ldap
|
||||
* python-ldap
|
||||
* Python SQLite
|
||||
* Python Standard Library
|
||||
* PyYAML
|
||||
* Request
|
||||
* Requests
|
||||
* SQLAlchemy
|
||||
* ssl
|
||||
// Docker
|
||||
* Wget
|
||||
|
@ -1,3 +1,2 @@
|
||||
Here is an example of an Elliptic Curve (EC) initialization. It implicitly
|
||||
generates a private key whose size is indicated in the algorithm name:
|
||||
|
||||
generates a private key whose size is indicated in the elliptic curve name:
|
||||
|
@ -1,5 +1,5 @@
|
||||
As a rule of thumb, use the cryptographic algorithms and mechanisms that are
|
||||
considered strong by the cryptographic community.
|
||||
considered strong by the cryptography community.
|
||||
|
||||
The appropriate choices are the following.
|
||||
|
||||
@ -8,7 +8,9 @@ The appropriate choices are the following.
|
||||
The security of these algorithms depends on the difficulty of attacks
|
||||
attempting to solve their underlying mathematical problem.
|
||||
|
||||
In general, a minimum key size of *2048* bits is recommended for both.
|
||||
In general, a minimum key size of *2048* bits is recommended for both. It
|
||||
provides 112 bits of security. A key length of *3072* or *4092* should be
|
||||
preferred when possible.
|
||||
|
||||
==== AES (Advanced Encryption Standard)
|
||||
|
||||
@ -24,8 +26,19 @@ Currently, a minimum key size of *128 bits* is recommended for AES.
|
||||
==== Elliptic Curve Cryptography (ECC)
|
||||
|
||||
Elliptic curve cryptography is also used in various algorithms, such as ECDSA,
|
||||
ECDH, or ECMQV. The length of keys generated with elliptic curve algorithms are mentioned
|
||||
ECDH, or ECMQV. The length of keys generated with elliptic curve algorithms is mentioned
|
||||
directly in their names. For example, `secp256k1` generates a 256-bits long
|
||||
private key.
|
||||
|
||||
Currently, a minimum key size of *224 bits* is recommended for EC algorithms.
|
||||
Currently, a minimum key size of *224 bits* is recommended for EC-based
|
||||
algorithms.
|
||||
|
||||
Additionally, some curves that theoretically provide sufficiently long keys are
|
||||
still discouraged. This can be because of a flaw in the curve parameters, a bad
|
||||
overall design, or poor performance. It is generally advised to use a
|
||||
NIST-approved elliptic curve wherever possible. Such curves currently include:
|
||||
|
||||
* NIST P curves with a size of at least 224 bits, e.g. secp256r1.
|
||||
* Curve25519, generally known as ed25519 or x25519 depending on its application.
|
||||
* Curve448.
|
||||
* Brainpool curves with a size of at least 224 bits, e.g. brainpoolP224r1
|
||||
|
@ -0,0 +1,4 @@
|
||||
** Documentation
|
||||
|
||||
* NIST Documentation - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-186.pdf[NIST SP 800-186: Recommendations for Discrete Logarithm-based Cryptography: Elliptic Curve Domain Parameters]
|
||||
* IETF - https://datatracker.ietf.org/doc/html/rfc5639[rfc5639: Elliptic Curve Cryptography (ECC) Brainpool Standard Curves and Curve Generation]
|
61
rules/S4426/python/how-to-fix-it/pyOpenSSL.adoc
Normal file
61
rules/S4426/python/how-to-fix-it/pyOpenSSL.adoc
Normal file
@ -0,0 +1,61 @@
|
||||
== How to fix it in pyOpenSSL
|
||||
|
||||
=== Code examples
|
||||
|
||||
include::../../common/fix/code-rationale.adoc[]
|
||||
|
||||
==== Noncompliant code example
|
||||
|
||||
include::../../common/fix/rsa.adoc[]
|
||||
|
||||
[source,python,diff-id=4,diff-type=noncompliant]
|
||||
----
|
||||
from OpenSSL.crypto import PKey, TYPE_RSA
|
||||
|
||||
key_rsa1024 = PKey()
|
||||
key_rsa1024.generate_key(type=TYPE_RSA, bits=1024) # Noncompliant
|
||||
----
|
||||
|
||||
include::../../common/fix/dsa.adoc[]
|
||||
|
||||
[source,python,diff-id=5,diff-type=noncompliant]
|
||||
----
|
||||
from OpenSSL.crypto import PKey, TYPE_DSA
|
||||
|
||||
key_dsa1024 = PKey()
|
||||
key_dsa1024.generate_key(type=TYPE_DSA, bits=1024) # Noncompliant
|
||||
----
|
||||
|
||||
==== Compliant solution
|
||||
|
||||
[source,python,diff-id=4,diff-type=compliant]
|
||||
----
|
||||
from OpenSSL.crypto import PKey, TYPE_RSA
|
||||
|
||||
key_rsa1024 = PKey()
|
||||
key_rsa1024.generate_key(type=TYPE_RSA, bits=3072)
|
||||
----
|
||||
|
||||
[source,python,diff-id=5,diff-type=compliant]
|
||||
----
|
||||
from OpenSSL.crypto import PKey, TYPE_DSA
|
||||
|
||||
key_dsa1024 = PKey()
|
||||
key_dsa1024.generate_key(type=TYPE_DSA, bits=3072)
|
||||
----
|
||||
|
||||
=== How does this work?
|
||||
|
||||
As a rule of thumb, use the cryptographic algorithms and mechanisms that are
|
||||
considered strong by the cryptography community.
|
||||
|
||||
The security of the RSA and DSA algorithms depends on the difficulty of attacks
|
||||
attempting to solve their underlying mathematical problem.
|
||||
|
||||
In general, a minimum key size of *2048* bits is recommended for both. It
|
||||
provides 112 bits of security. A key length of *3072* or *4096* should be
|
||||
preferred when possible.
|
||||
|
||||
=== Going the extra mile
|
||||
|
||||
include::../../common/extra-mile/pre-quantum.adoc[]
|
@ -34,14 +34,14 @@ public_key = private_key.public_key()
|
||||
|
||||
include::../../common/fix/ec.adoc[]
|
||||
|
||||
[source,python,diff-id=4,diff-type=noncompliant]
|
||||
[source,python,diff-id=3,diff-type=noncompliant]
|
||||
----
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
|
||||
backend = default_backend()
|
||||
|
||||
private_key = ec.generate_private_key(curve=ec.SECT163R2, backend=backend) # Noncompliant
|
||||
private_key = ec.generate_private_key(curve=ec.SECT163R2(), backend=backend) # Noncompliant
|
||||
public_key = private_key.public_key()
|
||||
----
|
||||
|
||||
@ -54,7 +54,7 @@ from cryptography.hazmat.backends import default_backend
|
||||
|
||||
backend = default_backend()
|
||||
|
||||
private_key = rsa.generate_private_key(key_size = 2048, backend = backend)
|
||||
private_key = rsa.generate_private_key(key_size = 3072, backend = backend)
|
||||
public_key = private_key.public_key()
|
||||
----
|
||||
|
||||
@ -65,18 +65,18 @@ from cryptography.hazmat.backends import default_backend
|
||||
|
||||
backend = default_backend()
|
||||
|
||||
private_key = dsa.generate_private_key(key_size = 2048, backend = backend)
|
||||
private_key = dsa.generate_private_key(key_size = 3072, backend = backend)
|
||||
public_key = private_key.public_key()
|
||||
----
|
||||
|
||||
[source,python,diff-id=4,diff-type=compliant]
|
||||
[source,python,diff-id=3,diff-type=compliant]
|
||||
----
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
|
||||
backend = default_backend()
|
||||
|
||||
private_key = ec.generate_private_key(curve=ec.SECT409R1, backend=backend)
|
||||
private_key = ec.generate_private_key(curve=ec.SECP521R1(), backend=backend)
|
||||
public_key = private_key.public_key()
|
||||
----
|
||||
|
||||
|
65
rules/S4426/python/how-to-fix-it/pycryptodome.adoc
Normal file
65
rules/S4426/python/how-to-fix-it/pycryptodome.adoc
Normal file
@ -0,0 +1,65 @@
|
||||
== How to fix it in Cryptodome
|
||||
|
||||
=== Code examples
|
||||
|
||||
include::../../common/fix/code-rationale.adoc[]
|
||||
|
||||
==== Noncompliant code example
|
||||
|
||||
include::../../common/fix/rsa.adoc[]
|
||||
|
||||
[source,python,diff-id=6,diff-type=noncompliant]
|
||||
----
|
||||
from Crypto.PublicKey import RSA
|
||||
|
||||
key_rsa1024 = RSA.generate(1024) # Noncompliant
|
||||
----
|
||||
|
||||
include::../../common/fix/dsa.adoc[]
|
||||
|
||||
[source,python,diff-id=7,diff-type=noncompliant]
|
||||
----
|
||||
from Crypto.PublicKey import DSA
|
||||
|
||||
key_dsa1024 = DSA.generate(1024) # Noncompliant
|
||||
----
|
||||
|
||||
include::../../common/fix/ec.adoc[]
|
||||
|
||||
[source,python,diff-id=8,diff-type=noncompliant]
|
||||
----
|
||||
from Crypto.PublicKey import DSA
|
||||
|
||||
key_p192 = ECC.generate(curve="secp192r1") # Noncompliant
|
||||
----
|
||||
|
||||
==== Compliant solution
|
||||
|
||||
[source,python,diff-id=6,diff-type=compliant]
|
||||
----
|
||||
from Crypto.PublicKey import RSA
|
||||
|
||||
key_rsa1024 = RSA.generate(3072)
|
||||
----
|
||||
|
||||
[source,python,diff-id=7,diff-type=compliant]
|
||||
----
|
||||
from Crypto.PublicKey import DSA
|
||||
|
||||
key_dsa1024 = DSA.generate(3072)
|
||||
----
|
||||
|
||||
[source,python,diff-id=8,diff-type=compliant]
|
||||
----
|
||||
from Crypto.PublicKey import DSA
|
||||
|
||||
key_ed25519 = ECC.generate(curve="ed25519")
|
||||
----
|
||||
|
||||
=== How does this work?
|
||||
|
||||
include::../../common/fix/fix.adoc[]
|
||||
|
||||
=== Going the extra mile
|
||||
|
||||
include::../../common/extra-mile/pre-quantum.adoc[]
|
@ -10,6 +10,10 @@ include::../impact.adoc[]
|
||||
|
||||
include::how-to-fix-it/pyca.adoc[]
|
||||
|
||||
include::how-to-fix-it/pycryptodome.adoc[][]
|
||||
|
||||
include::how-to-fix-it/pyOpenSSL.adoc[][]
|
||||
|
||||
== Resources
|
||||
|
||||
include::../common/resources/docs.adoc[]
|
||||
|
Loading…
x
Reference in New Issue
Block a user