Skip to content

Instantly share code, notes, and snippets.

@giautm
Created June 11, 2019 09:25
Show Gist options
  • Save giautm/dc0739cfe9450e19c3fde83d0722252e to your computer and use it in GitHub Desktop.
Save giautm/dc0739cfe9450e19c3fde83d0722252e to your computer and use it in GitHub Desktop.
package md5crypt
import (
"crypto/md5"
"fmt"
"strings"
"testing"
)
func TestMD5crypt(t *testing.T) {
result := MD5crypt([]byte("1234"), []byte("GVYkFcwv"), []byte("$1$"))
fmt.Println(result)
if result != "$1$GVYkFcwv$wzUAmJjs/zNImk6jT2UjN." {
t.Errorf("Invalid result: %s", result)
}
}
const itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var (
arr = [][]int{
[]int{0, 6, 12},
[]int{1, 7, 13},
[]int{2, 8, 14},
[]int{3, 9, 15},
[]int{4, 10, 5},
}
)
func MD5crypt(rawPass, salt, magic []byte) string {
hash := md5.New()
hash.Write(rawPass)
hash.Write(magic)
hash.Write(salt)
st := md5.New()
st.Write(rawPass)
st.Write(salt)
st.Write(rawPass)
stretch := st.Sum(nil)
for i := 0; i < len(rawPass); i++ {
hash.Write([]byte{stretch[i%16]})
}
i := len(rawPass)
for i > 0 {
if i&1 > 0 {
hash.Write([]byte{0})
} else {
hash.Write([]byte{rawPass[0]})
}
i >>= 1
}
saltedMD5 := hash.Sum(nil)
for i = 0; i < 1000; i++ {
hash.Reset()
if i&1 > 0 {
hash.Write(rawPass)
} else {
hash.Write(saltedMD5)
}
if i%3 > 0 {
hash.Write(salt)
}
if i%7 > 0 {
hash.Write(rawPass)
}
if i&1 > 0 {
hash.Write(saltedMD5)
} else {
hash.Write(rawPass)
}
saltedMD5 = hash.Sum(nil)
}
builder := strings.Builder{}
builder.WriteString(string(magic))
builder.WriteString(string(salt))
builder.WriteRune('$')
for _, subArr := range arr {
v := int(saltedMD5[subArr[0]])<<16 |
int(saltedMD5[subArr[1]])<<8 |
int(saltedMD5[subArr[2]])
for i := 0; i < 4; i++ {
builder.WriteRune(rune(itoa64[v&0x3f]))
v >>= 6
}
}
v := int(saltedMD5[11])
for i := 0; i < 2; i++ {
builder.WriteRune(rune(itoa64[v&0x3f]))
v >>= 6
}
return builder.String()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment