Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
e92ef13b
Kaydet (Commit)
e92ef13b
authored
Eki 12, 2013
tarafından
Christian Heimes
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue #18582: Add 'pbkdf2_hmac' to the hashlib module.
üst
3892419a
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
280 additions
and
0 deletions
+280
-0
hashlib.rst
Doc/library/hashlib.rst
+43
-0
3.4.rst
Doc/whatsnew/3.4.rst
+8
-0
hashlib.py
Lib/hashlib.py
+8
-0
test_hashlib.py
Lib/test/test_hashlib.py
+82
-0
NEWS
Misc/NEWS
+3
-0
_hashopenssl.c
Modules/_hashopenssl.c
+136
-0
No files found.
Doc/library/hashlib.rst
Dosyayı görüntüle @
e92ef13b
...
@@ -32,6 +32,10 @@ digests. The modern term is secure hash.
...
@@ -32,6 +32,10 @@ digests. The modern term is secure hash.
Some algorithms have known hash collision weaknesses, refer to the "See
Some algorithms have known hash collision weaknesses, refer to the "See
also" section at the end.
also" section at the end.
Hash algorithms
---------------
There is one constructor method named for each type of :dfn:`hash`. All return
There is one constructor method named for each type of :dfn:`hash`. All return
a hash object with the same simple interface. For example: use :func:`sha1` to
a hash object with the same simple interface. For example: use :func:`sha1` to
create a SHA1 hash object. You can now feed this object with :term:`bytes-like
create a SHA1 hash object. You can now feed this object with :term:`bytes-like
...
@@ -174,6 +178,43 @@ A hash object has the following methods:
...
@@ -174,6 +178,43 @@ A hash object has the following methods:
compute the digests of data sharing a common initial substring.
compute the digests of data sharing a common initial substring.
Key Derivation Function
-----------------------
Key derivation and key stretching algorithms are designed for secure password
hashing. Naive algorithms such as ``sha1(password)`` are not resistant
against brute-force attacks. A good password hashing function must be tunable,
slow and include a salt.
.. function:: pbkdf2_hmac(name, password, salt, rounds, dklen=None)
The function provides PKCS#5 password-based key derivation function 2. It
uses HMAC as pseudorandom function.
The string *name* is the desired name of the hash digest algorithm for
HMAC, e.g. 'sha1' or 'sha256'. *password* and *salt* are interpreted as
buffers of bytes. Applications and libraries should limit *password* to
a sensible value (e.g. 1024). *salt* should be about 16 or more bytes from
a proper source, e.g. :func:`os.urandom`.
The number of *rounds* should be chosen based on the hash algorithm and
computing power. As of 2013 a value of at least 100,000 rounds of SHA-256
have been suggested.
*dklen* is the length of the derived key. If *dklen* is ``None`` then the
digest size of the hash algorithm *name* is used, e.g. 64 for SHA-512.
>>> import hashlib, binascii
>>> dk = hashlib.pbkdf2_hmac('sha256', b'password', b'salt', 100000)
>>> binascii.hexlify(dk)
b'0394a2ede332c9a13eb82e9b24631604c31df978b4e2f0fbd2c549944f9d79a5'
.. versionadded:: 3.4
.. note:: *pbkdf2_hmac* is only available with OpenSSL 1.0 and newer.
.. seealso::
.. seealso::
Module :mod:`hmac`
Module :mod:`hmac`
...
@@ -189,3 +230,5 @@ A hash object has the following methods:
...
@@ -189,3 +230,5 @@ A hash object has the following methods:
Wikipedia article with information on which algorithms have known issues and
Wikipedia article with information on which algorithms have known issues and
what that means regarding their use.
what that means regarding their use.
http://www.ietf.org/rfc/rfc2898.txt
PKCS #5: Password-Based Cryptography Specification Version 2.0
Doc/whatsnew/3.4.rst
Dosyayı görüntüle @
e92ef13b
...
@@ -261,6 +261,14 @@ functools
...
@@ -261,6 +261,14 @@ functools
New :func:`functools.singledispatch` decorator: see the :pep:`443`.
New :func:`functools.singledispatch` decorator: see the :pep:`443`.
hashlib
-------
New :func:`hashlib.pbkdf2_hmac` function.
(Contributed by Christian Heimes in :issue:`18582`)
inspect
inspect
-------
-------
...
...
Lib/hashlib.py
Dosyayı görüntüle @
e92ef13b
...
@@ -147,6 +147,14 @@ except ImportError:
...
@@ -147,6 +147,14 @@ except ImportError:
new
=
__py_new
new
=
__py_new
__get_hash
=
__get_builtin_constructor
__get_hash
=
__get_builtin_constructor
# PBKDF2 requires OpenSSL 1.0+ with HMAC and SHA
try
:
from
_hashlib
import
pbkdf2_hmac
except
ImportError
:
pass
else
:
__all__
+=
(
'pbkdf2_hmac'
,)
for
__func_name
in
__always_supported
:
for
__func_name
in
__always_supported
:
# try them all, some may not work due to the OpenSSL
# try them all, some may not work due to the OpenSSL
# version not supporting that algorithm.
# version not supporting that algorithm.
...
...
Lib/test/test_hashlib.py
Dosyayı görüntüle @
e92ef13b
...
@@ -545,6 +545,88 @@ class HashLibTestCase(unittest.TestCase):
...
@@ -545,6 +545,88 @@ class HashLibTestCase(unittest.TestCase):
self
.
assertEqual
(
expected_hash
,
hasher
.
hexdigest
())
self
.
assertEqual
(
expected_hash
,
hasher
.
hexdigest
())
pbkdf2_test_vectors
=
[
(
b
'password'
,
b
'salt'
,
1
,
None
),
(
b
'password'
,
b
'salt'
,
2
,
None
),
(
b
'password'
,
b
'salt'
,
4096
,
None
),
# too slow, it takes over a minute on a fast CPU.
#(b'password', b'salt', 16777216, None),
(
b
'passwordPASSWORDpassword'
,
b
'saltSALTsaltSALTsaltSALTsaltSALTsalt'
,
4096
,
-
1
),
(
b
'pass
\0
word'
,
b
'sa
\0
lt'
,
4096
,
16
),
]
pbkdf2_results
=
{
"sha1"
:
[
# offical test vectors from RFC 6070
(
bytes
.
fromhex
(
'0c60c80f961f0e71f3a9b524af6012062fe037a6'
),
None
),
(
bytes
.
fromhex
(
'ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'
),
None
),
(
bytes
.
fromhex
(
'4b007901b765489abead49d926f721d065a429c1'
),
None
),
#(bytes.fromhex('eefe3d61cd4da4e4e9945b3d6ba2158c2634e984'), None),
(
bytes
.
fromhex
(
'3d2eec4fe41c849b80c8d83662c0e44a8b291a964c'
'f2f07038'
),
25
),
(
bytes
.
fromhex
(
'56fa6aa75548099dcc37d7f03425e0c3'
),
None
),],
"sha256"
:
[
(
bytes
.
fromhex
(
'120fb6cffcf8b32c43e7225256c4f837'
'a86548c92ccc35480805987cb70be17b'
),
None
),
(
bytes
.
fromhex
(
'ae4d0c95af6b46d32d0adff928f06dd0'
'2a303f8ef3c251dfd6e2d85a95474c43'
),
None
),
(
bytes
.
fromhex
(
'c5e478d59288c841aa530db6845c4c8d'
'962893a001ce4e11a4963873aa98134a'
),
None
),
#(bytes.fromhex('cf81c66fe8cfc04d1f31ecb65dab4089'
# 'f7f179e89b3b0bcb17ad10e3ac6eba46'), None),
(
bytes
.
fromhex
(
'348c89dbcbd32b2f32d814b8116e84cf2b17'
'347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9'
),
40
),
(
bytes
.
fromhex
(
'89b69d0516f829893c696226650a8687'
),
None
),],
"sha512"
:
[
(
bytes
.
fromhex
(
'867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5'
'd513554e1c8cf252c02d470a285a0501bad999bfe943c08f'
'050235d7d68b1da55e63f73b60a57fce'
),
None
),
(
bytes
.
fromhex
(
'e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f004071'
'3f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82'
'be67335c77a6068e04112754f27ccf4e'
),
None
),
(
bytes
.
fromhex
(
'd197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f8'
'7f6902e072f457b5143f30602641b3d55cd335988cb36b84'
'376060ecd532e039b742a239434af2d5'
),
None
),
(
bytes
.
fromhex
(
'8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b8'
'68c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30'
'225c583a186cd82bd4daea9724a3d3b8'
),
64
),
(
bytes
.
fromhex
(
'9d9e9c4cd21fe4be24d5b8244c759665'
),
None
),],
}
@unittest.skipUnless
(
hasattr
(
hashlib
,
'pbkdf2_hmac'
),
'pbkdf2_hmac required for this test.'
)
def
test_pbkdf2_hmac
(
self
):
pbkdf2
=
hashlib
.
pbkdf2_hmac
for
digest_name
,
results
in
self
.
pbkdf2_results
.
items
():
for
i
,
vector
in
enumerate
(
self
.
pbkdf2_test_vectors
):
password
,
salt
,
rounds
,
dklen
=
vector
expected
,
overwrite_dklen
=
results
[
i
]
if
overwrite_dklen
:
dklen
=
overwrite_dklen
out
=
pbkdf2
(
digest_name
,
password
,
salt
,
rounds
,
dklen
)
self
.
assertEqual
(
out
,
expected
,
(
digest_name
,
password
,
salt
,
rounds
,
dklen
))
out
=
pbkdf2
(
digest_name
,
memoryview
(
password
),
memoryview
(
salt
),
rounds
,
dklen
)
out
=
pbkdf2
(
digest_name
,
bytearray
(
password
),
bytearray
(
salt
),
rounds
,
dklen
)
self
.
assertEqual
(
out
,
expected
)
if
dklen
is
None
:
out
=
pbkdf2
(
digest_name
,
password
,
salt
,
rounds
)
self
.
assertEqual
(
out
,
expected
,
(
digest_name
,
password
,
salt
,
rounds
))
self
.
assertRaises
(
TypeError
,
pbkdf2
,
b
'sha1'
,
b
'pass'
,
b
'salt'
,
1
)
self
.
assertRaises
(
TypeError
,
pbkdf2
,
'sha1'
,
'pass'
,
'salt'
,
1
)
self
.
assertRaises
(
ValueError
,
pbkdf2
,
'sha1'
,
b
'pass'
,
b
'salt'
,
0
)
self
.
assertRaises
(
ValueError
,
pbkdf2
,
'sha1'
,
b
'pass'
,
b
'salt'
,
-
1
)
self
.
assertRaises
(
ValueError
,
pbkdf2
,
'sha1'
,
b
'pass'
,
b
'salt'
,
1
,
0
)
self
.
assertRaises
(
ValueError
,
pbkdf2
,
'sha1'
,
b
'pass'
,
b
'salt'
,
1
,
-
1
)
with
self
.
assertRaisesRegex
(
ValueError
,
'unsupported hash type'
):
pbkdf2
(
'unknown'
,
b
'pass'
,
b
'salt'
,
1
)
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
unittest
.
main
()
unittest
.
main
()
Misc/NEWS
Dosyayı görüntüle @
e92ef13b
...
@@ -42,6 +42,9 @@ Core and Builtins
...
@@ -42,6 +42,9 @@ Core and Builtins
Library
Library
-------
-------
- Issue #18582: Add '
pbkdf2_hmac
' to the hashlib module. It implements PKCS#5
password-based key derivation functions with HMAC as pseudorandom function.
- Issue #19131: The aifc module now correctly reads and writes sampwidth of
- Issue #19131: The aifc module now correctly reads and writes sampwidth of
compressed streams.
compressed streams.
...
...
Modules/_hashopenssl.c
Dosyayı görüntüle @
e92ef13b
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#include <openssl/evp.h>
#include <openssl/evp.h>
/* We use the object interface to discover what hashes OpenSSL supports. */
/* We use the object interface to discover what hashes OpenSSL supports. */
#include <openssl/objects.h>
#include <openssl/objects.h>
#include "openssl/err.h"
#define MUNCH_SIZE INT_MAX
#define MUNCH_SIZE INT_MAX
...
@@ -61,6 +62,34 @@ DEFINE_CONSTS_FOR_NEW(sha384)
...
@@ -61,6 +62,34 @@ DEFINE_CONSTS_FOR_NEW(sha384)
DEFINE_CONSTS_FOR_NEW
(
sha512
)
DEFINE_CONSTS_FOR_NEW
(
sha512
)
#endif
#endif
static
PyObject
*
_setException
(
PyObject
*
exc
)
{
unsigned
long
errcode
;
const
char
*
lib
,
*
func
,
*
reason
;
errcode
=
ERR_peek_last_error
();
if
(
!
errcode
)
{
PyErr_SetString
(
exc
,
"unknown reasons"
);
return
NULL
;
}
ERR_clear_error
();
lib
=
ERR_lib_error_string
(
errcode
);
func
=
ERR_func_error_string
(
errcode
);
reason
=
ERR_reason_error_string
(
errcode
);
if
(
lib
&&
func
)
{
PyErr_Format
(
exc
,
"[%s: %s] %s"
,
lib
,
func
,
reason
);
}
else
if
(
lib
)
{
PyErr_Format
(
exc
,
"[%s] %s"
,
lib
,
reason
);
}
else
{
PyErr_SetString
(
exc
,
reason
);
}
return
NULL
;
}
static
EVPobject
*
static
EVPobject
*
newEVPobject
(
PyObject
*
name
)
newEVPobject
(
PyObject
*
name
)
...
@@ -466,6 +495,109 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
...
@@ -466,6 +495,109 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
return
ret_obj
;
return
ret_obj
;
}
}
#if (OPENSSL_VERSION_NUMBER >= 0x10000000 && !defined(OPENSSL_NO_HMAC) \
&& !defined(OPENSSL_NO_SHA))
#define PY_PBKDF2_HMAC 1
PyDoc_STRVAR
(
pbkdf2_hmac__doc__
,
"pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None) -> key
\n
\
\n
\
Password based key derivation function 2 (PKCS #5 v2.0) with HMAC as
\n
\
pseudorandom function."
);
static
PyObject
*
pbkdf2_hmac
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kwdict
)
{
static
char
*
kwlist
[]
=
{
"hash_name"
,
"password"
,
"salt"
,
"iterations"
,
"dklen"
,
NULL
};
PyObject
*
key_obj
=
NULL
,
*
dklen_obj
=
Py_None
;
char
*
name
,
*
key
;
Py_buffer
password
,
salt
;
long
iterations
,
dklen
;
int
retval
;
const
EVP_MD
*
digest
;
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwdict
,
"sy*y*l|O:pbkdf2_hmac"
,
kwlist
,
&
name
,
&
password
,
&
salt
,
&
iterations
,
&
dklen_obj
))
{
return
NULL
;
}
digest
=
EVP_get_digestbyname
(
name
);
if
(
digest
==
NULL
)
{
PyErr_SetString
(
PyExc_ValueError
,
"unsupported hash type"
);
goto
end
;
}
if
(
password
.
len
>
INT_MAX
)
{
PyErr_SetString
(
PyExc_OverflowError
,
"password is too long."
);
goto
end
;
}
if
(
salt
.
len
>
INT_MAX
)
{
PyErr_SetString
(
PyExc_OverflowError
,
"salt is too long."
);
goto
end
;
}
if
(
iterations
<
1
)
{
PyErr_SetString
(
PyExc_ValueError
,
"iteration value must be greater than 0."
);
goto
end
;
}
if
(
iterations
>
INT_MAX
)
{
PyErr_SetString
(
PyExc_OverflowError
,
"iteration value is too great."
);
goto
end
;
}
if
(
dklen_obj
==
Py_None
)
{
dklen
=
EVP_MD_size
(
digest
);
}
else
{
dklen
=
PyLong_AsLong
(
dklen_obj
);
if
((
dklen
==
-
1
)
&&
PyErr_Occurred
())
{
goto
end
;
}
}
if
(
dklen
<
1
)
{
PyErr_SetString
(
PyExc_ValueError
,
"key length must be greater than 0."
);
goto
end
;
}
if
(
dklen
>
INT_MAX
)
{
/* INT_MAX is always smaller than dkLen max (2^32 - 1) * hLen */
PyErr_SetString
(
PyExc_OverflowError
,
"key length is too great."
);
goto
end
;
}
key_obj
=
PyBytes_FromStringAndSize
(
NULL
,
dklen
);
if
(
key_obj
==
NULL
)
{
goto
end
;
}
key
=
PyBytes_AS_STRING
(
key_obj
);
Py_BEGIN_ALLOW_THREADS
retval
=
PKCS5_PBKDF2_HMAC
((
char
*
)
password
.
buf
,
password
.
len
,
(
unsigned
char
*
)
salt
.
buf
,
salt
.
len
,
iterations
,
digest
,
dklen
,
(
unsigned
char
*
)
key
);
Py_END_ALLOW_THREADS
if
(
!
retval
)
{
Py_CLEAR
(
key_obj
);
_setException
(
PyExc_ValueError
);
goto
end
;
}
end:
PyBuffer_Release
(
&
password
);
PyBuffer_Release
(
&
salt
);
return
key_obj
;
}
#endif
/* State for our callback function so that it can accumulate a result. */
/* State for our callback function so that it can accumulate a result. */
typedef
struct
_internal_name_mapper_state
{
typedef
struct
_internal_name_mapper_state
{
...
@@ -588,6 +720,10 @@ GEN_CONSTRUCTOR(sha512)
...
@@ -588,6 +720,10 @@ GEN_CONSTRUCTOR(sha512)
static
struct
PyMethodDef
EVP_functions
[]
=
{
static
struct
PyMethodDef
EVP_functions
[]
=
{
{
"new"
,
(
PyCFunction
)
EVP_new
,
METH_VARARGS
|
METH_KEYWORDS
,
EVP_new__doc__
},
{
"new"
,
(
PyCFunction
)
EVP_new
,
METH_VARARGS
|
METH_KEYWORDS
,
EVP_new__doc__
},
#ifdef PY_PBKDF2_HMAC
{
"pbkdf2_hmac"
,
(
PyCFunction
)
pbkdf2_hmac
,
METH_VARARGS
|
METH_KEYWORDS
,
pbkdf2_hmac__doc__
},
#endif
CONSTRUCTOR_METH_DEF
(
md5
),
CONSTRUCTOR_METH_DEF
(
md5
),
CONSTRUCTOR_METH_DEF
(
sha1
),
CONSTRUCTOR_METH_DEF
(
sha1
),
#ifdef _OPENSSL_SUPPORTS_SHA2
#ifdef _OPENSSL_SUPPORTS_SHA2
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment