initial commit
This commit is contained in:
commit
78673c0967
4 changed files with 200 additions and 0 deletions
24
LICENSE
Normal file
24
LICENSE
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
Copyright (c) 2016, ston1th
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* The names of the authors and/or contributors may not be used to
|
||||
endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL ston1th BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
7
README.md
Normal file
7
README.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# gomp - MasterPassword written in Go
|
||||
|
||||
gomp is the golang implementation of the MasterPassword algorithm.
|
||||
|
||||
## Sources
|
||||
* http://masterpasswordapp.com/algorithm.html
|
||||
* https://github.com/Lyndir/MasterPassword
|
||||
151
gomp.go
Normal file
151
gomp.go
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
package mp
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"golang.org/x/crypto/scrypt"
|
||||
"runtime"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type TemplateType int
|
||||
|
||||
const (
|
||||
MaximumSecurityPassword TemplateType = iota
|
||||
LongPassword
|
||||
MediumPassword
|
||||
BasicPassword
|
||||
ShortPassword
|
||||
PIN
|
||||
Name
|
||||
Phrase
|
||||
)
|
||||
|
||||
const variant = "com.lyndir.masterpassword"
|
||||
|
||||
var (
|
||||
typeMap = map[TemplateType][]string{
|
||||
MaximumSecurityPassword: {
|
||||
"anoxxxxxxxxxxxxxxxxx",
|
||||
"axxxxxxxxxxxxxxxxxno",
|
||||
},
|
||||
LongPassword: {
|
||||
"CvcvnoCvcvCvcv",
|
||||
"CvcvCvcvnoCvcv",
|
||||
"CvcvCvcvCvcvno",
|
||||
"CvccnoCvcvCvcv",
|
||||
"CvccCvcvnoCvcv",
|
||||
"CvccCvcvCvcvno",
|
||||
"CvcvnoCvccCvcv",
|
||||
"CvcvCvccnoCvcv",
|
||||
"CvcvCvccCvcvno",
|
||||
"CvcvnoCvcvCvcc",
|
||||
"CvcvCvcvnoCvcc",
|
||||
"CvcvCvcvCvccno",
|
||||
"CvccnoCvccCvcv",
|
||||
"CvccCvccnoCvcv",
|
||||
"CvccCvccCvcvno",
|
||||
"CvcvnoCvccCvcc",
|
||||
"CvcvCvccnoCvcc",
|
||||
"CvcvCvccCvccno",
|
||||
"CvccnoCvcvCvcc",
|
||||
"CvccCvcvnoCvcc",
|
||||
"CvccCvcvCvccno",
|
||||
},
|
||||
MediumPassword: {
|
||||
"CvcnoCvc",
|
||||
"CvcCvcno",
|
||||
},
|
||||
BasicPassword: {
|
||||
"aaanaaan",
|
||||
"aannaaan",
|
||||
"aaannaaa",
|
||||
},
|
||||
ShortPassword: {
|
||||
"Cvcn",
|
||||
},
|
||||
PIN: {
|
||||
"nnnn",
|
||||
},
|
||||
Name: {
|
||||
"cvccvcvcv",
|
||||
},
|
||||
Phrase: {
|
||||
"cvcc cvc cvccvcv cvc",
|
||||
"cvc cvccvcvcv cvcv",
|
||||
"cv cvccv cvc cvcvccv",
|
||||
},
|
||||
}
|
||||
charMap = map[rune]string{
|
||||
'V': "AEIOU",
|
||||
'C': "BCDFGHJKLMNPQRSTVWXYZ",
|
||||
'v': "aeiou",
|
||||
'c': "bcdfghjklmnpqrstvwxyz",
|
||||
'A': "AEIOUBCDFGHJKLMNPQRSTVWXYZ",
|
||||
'a': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz",
|
||||
'n': "0123456789",
|
||||
'o': "@&%?,=[]_:-+*$#!'^~;()/.",
|
||||
'x': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()",
|
||||
' ': " ",
|
||||
}
|
||||
)
|
||||
|
||||
func i2b(i int) (b []byte) {
|
||||
b = make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(b, uint32(i))
|
||||
return
|
||||
}
|
||||
|
||||
type MP struct {
|
||||
sync.Mutex
|
||||
key []byte
|
||||
}
|
||||
|
||||
func NewMP(p, name []byte) (*MP, error) {
|
||||
salt := []byte(variant)
|
||||
salt = append(salt, i2b(len(name))...)
|
||||
salt = append(salt, name...)
|
||||
key, err := scrypt.Key(p, salt, 32768, 8, 2, 64)
|
||||
defer func() {
|
||||
for i := range p {
|
||||
p[i] = byte(0)
|
||||
}
|
||||
for i := range name {
|
||||
name[i] = byte(0)
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &MP{key: key}, nil
|
||||
}
|
||||
|
||||
func (mp *MP) PrintPassword(site string, counter int, tempType TemplateType) {
|
||||
mp.Lock()
|
||||
defer mp.Unlock()
|
||||
salt := []byte(variant)
|
||||
salt = append(salt, i2b(len(site))...)
|
||||
salt = append(salt, []byte(site)...)
|
||||
salt = append(salt, i2b(counter)...)
|
||||
mac := hmac.New(sha256.New, mp.key)
|
||||
mac.Write(salt)
|
||||
seed := mac.Sum(nil)
|
||||
templates := typeMap[tempType]
|
||||
temp := templates[int(seed[0])%len(templates)]
|
||||
for i, c := range temp {
|
||||
chars := charMap[c]
|
||||
print(string(chars[int(seed[i+1])%len(chars)]))
|
||||
}
|
||||
print("\n")
|
||||
}
|
||||
|
||||
func (mp *MP) DestroyKey() {
|
||||
mp.Lock()
|
||||
for i := range mp.key {
|
||||
mp.key[i] = byte(0)
|
||||
}
|
||||
mp.key = nil
|
||||
runtime.GC()
|
||||
mp.Unlock()
|
||||
}
|
||||
18
gomp_test.go
Normal file
18
gomp_test.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package mp
|
||||
|
||||
import "testing"
|
||||
|
||||
func test(t *testing.T) {
|
||||
pw := []byte("1")
|
||||
name := []byte("1")
|
||||
mp, _ := NewMP(pw, name)
|
||||
mp.PrintPassword("1", 1, MaximumSecurityPassword)
|
||||
mp.PrintPassword("1", 1, LongPassword)
|
||||
mp.PrintPassword("1", 1, MediumPassword)
|
||||
mp.PrintPassword("1", 1, BasicPassword)
|
||||
mp.PrintPassword("1", 1, ShortPassword)
|
||||
mp.PrintPassword("1", 1, PIN)
|
||||
mp.PrintPassword("1", 1, Name)
|
||||
mp.DestroyKey()
|
||||
mp.PrintPassword("1", 1, Phrase)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue