Drupal password hasher for migration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
"""
DrupalPasswordHasher

To use, put this in any app and add to your settings.py, something like this:

PASSWORD_HASHERS = (
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'myproject.myapp.drupal_hasher.DrupalPasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.BCryptPasswordHasher',
    'django.contrib.auth.hashers.SHA1PasswordHasher',
    'django.contrib.auth.hashers.MD5PasswordHasher',
    'django.contrib.auth.hashers.CryptPasswordHasher',
)

Two notes: First, in Drupal the number of iterations is a multiple of 2,
which is represented by the first character after the $, so set the iterations
class member appropriately.

Secondly, in Drupal the passwords are stored as:

$S$<hash>

while in Django the passwords are stored as

S$<hash>

So you must cut off the first character of each password when migrating.
"""

import hashlib

from django.contrib.auth.hashers import BasePasswordHasher

_ITOA64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'


class DrupalPasswordHasher(BasePasswordHasher):
    algorithm = "S"
    iter_code = 'C'
    salt_length = 8

    def encode(self, password, salt, iter_code=None):
        """The Drupal 7 method of encoding passwords"""
        if iter_code == None:
            iterations = 2 ** _ITOA64.index(self.iter_code)
        else:
            iterations = 2 ** _ITOA64.index(iter_code)
        hash = hashlib.sha512(salt + password).digest()

        for i in range(iterations):
            hash = hashlib.sha512(hash + password).digest()

        l = len(hash)

        output = ''
        i = 0

        while i < l:
            value = ord(hash[i])
            i = i + 1

            output += _ITOA64[value & 0x3f]
            if i < l:
                value |= ord(hash[i]) << 8

            output += _ITOA64[(value >> 6) & 0x3f]
            if i >= l:
                break
            i += 1

            if i < l:
                value |= ord(hash[i]) << 16

            output += _ITOA64[(value >> 12) & 0x3f]
            if i >= l:
                break
            i += 1

            output += _ITOA64[(value >> 18) & 0x3f]

        longhashed = "%s$%s%s%s" % (self.algorithm, iter_code,
                                    salt, output)
        return longhashed[:54]

    def verify(self, password, encoded):
        hash = encoded.split("$")[1]
        iter_code = hash[0]
        salt = hash[1:1 + self.salt_length]
        return encoded == self.encode(password, salt, iter_code)

More like this

  1. Use crypt instead of sha1 as password hash algorithm by akaihola 5 years, 8 months ago
  2. Old MySQL Password Hash by tback 4 years ago
  3. Sorl thumbs for the lazy by renyi 1 year, 12 months ago
  4. Serialize JSON object into a model object and retrieve a python dictionary on load by cstrap 2 years, 6 months ago
  5. drupal7 password check by bram 11 months ago

Comments

XaviColomer (on May 23, 2012):

Hi,

I am having some problems with this snippet. People can login OK, but User class seems not to react ok with this.

For example, when I try to open any user from inside the admin, i get this error:

Any idea?

NotImplementedError at /admin/auth/user/3663/ No exception supplied Request Method: GET Request URL: http://devcon.pre.is/admin/auth/user/3663/ Django Version: 1.4 Exception Type: NotImplementedError Exception Location: /usr/local/lib/python2.7/dist-packages/django/contrib/auth/hashers.py in safe_summary, line 184 Python Executable: /usr/bin/python Python Version: 2.7.2 Python Path:
['/home/sites/devcon.pre.is/private/devcon', '/usr/local/lib/python2.7/dist-packages/flup-1.0.3.dev_20110111-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/South-0.7.4-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/emencia.django.newsletter-0.3.dev-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/xlrd-0.7.7-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/django_tinymce-1.5.1b2-py2.7.egg', '/home/xavicolomer/packages/src/facebooksdk', '/usr/local/lib/python2.7/dist-packages/django_debug_toolbar-0.9.4-py2.7.egg', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/local/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7'] Server time: Wed, 16 May 2012 09:08:45 -0500

#

dgrtwo (on June 19, 2012):

XaviColomer: Sorry for the late response- I'm afraid I have no idea. Have you found the problem since?

#

bram (on June 22, 2012):

didn't work for me, so I rolled my own based on this one: http://djangosnippets.org/snippets/2777/

#

XaviColomer (on July 9, 2012):

dgrtwo can we discuss via email? you can contact me on info [] bcndevcon.org

#

siblek31 (on April 13, 2013):

Kesehatan pribadi agar cepat hamil tergantung sebagian pada isyarat aktif, pasif, dan dibantu orang mengamati dan mengadopsi tentang kesehatan mereka sendiri. Ini termasuk tindakan pribadi untuk mencegah atau meminimalkan soal ulangan sd efek dari penyakit, biasanya kondisi kronis, melalui perawatan integratif. Mereka juga termasuk praktek-praktek kebersihan pribadi belajar bahasa inggris cepat untuk mencegah infeksi dan penyakit, seperti mandi dan mencuci tangan dengan sabun, menyikat gigi dan flossing gigi, menyimpan, menyiapkan dan menangani makanan dengan aman, dan banyak lainnya. Informasi yang diperoleh dari pengamatan pribadi kehidupan sehari-hari - kursus teknisi komputer misalnya tentang pola tidur, perilaku latihan, asupan gizi, dan fitur here lingkungan - dapat digunakan untuk menginformasikan keputusan pribadi dan tindakan (misalnya, "Saya merasa lelah di pagi hari jadi saya akan cobalah tidur di bantal yang berbeda "), serta keputusan klinis dan rencana perawatan (misalnya, pasien yang memperhatikan nya sepatu ketat dari biasanya mungkin akan mengalami eksaserbasi kursus bahasa inggris gagal jantung sisi kiri, dan mungkin memerlukan pengobatan diuretik untuk mengurangi overload cairan). [26]

Kesehatan pribadi juga tergantung sebagian pada struktur sosial kehidupan seseorang. Pemeliharaan hubungan yang kuat sosial, relawan, dan kegiatan sosial lainnya telah dikaitkan dengan kesehatan mental yang positif dan bahkan umur panjang meningkat. Satu studi di Amerika antara senior mendapatkan uang dari internet di atas usia 70 menemukan bahwa sering relawan dikaitkan dengan penurunan risiko kematian dibandingkan dengan orang tua yang tidak sukarela, tanpa memandang status kesehatan fisik [27] Studi lain dari Singapura melaporkan bahwa relawan pensiunan memiliki kinerja kognitif secara signifikan lebih baik. skor, gejala depresi lebih sedikit, dan mental yang lebih baik baik makhluk dan kehidupan kepuasan daripada non-relawan pensiunan. [28]

#

psychok7 (on May 9, 2013):

thanks

#

(Forgotten your password?)