First code push
This commit is contained in:
8
.travis.yml
Normal file
8
.travis.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
|
||||
dist: xenial
|
||||
language: go
|
||||
|
||||
go:
|
||||
- master
|
||||
|
17
CHANGELOG.md
Normal file
17
CHANGELOG.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.0.0] - 2017-06-20
|
||||
### Added
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[Unreleased]: https://github.com/olivierlacan/keep-a-changelog/compare/v1.0.0...HEAD
|
||||
[1.0.0]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.3.0...v1.0.0
|
25
README.md
Normal file
25
README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# gaspass
|
||||
Store passwords without actually storing them
|
||||
|
||||
## How does it work?
|
||||
Ose one password for access all other passwords, but в отличии от does not store them on disk or in memory at all.
|
||||
Gaspass is more a password generator than password manager or store tool. Every run you will get the password and this password will be the same if you use the same parameters like length, character set, resource and private key.
|
||||
Work scheme is very similar to [lesspass](https://github.com/lesspass/lesspass), but uses modern [argon2id](https://en.wikipedia.org/wiki/Argon2) KDF (key derivation function) instead of PBKDF2-SHA1.
|
||||
|
||||
## Is it secure?
|
||||
Generally yes, but it depends on private key quality and "защиты ключа"
|
||||
|
||||
|
||||
|
||||
## ToDo
|
||||
[] Tests
|
||||
[] SECURITY.md
|
||||
[] Resource management
|
||||
[] GUI
|
||||
|
||||
|
||||
|
||||
Это шобы версии текстов основного файла
|
||||
|
||||
Compare this version with version of localized file to make sure toy read an actual information.
|
||||
README.md version 0
|
61
src/gaspass/main.go
Normal file
61
src/gaspass/main.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package gaspass
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"error"
|
||||
"golang.org/x/crypto/argon2"
|
||||
)
|
||||
|
||||
const (
|
||||
CharsLower string = "abcdefghijklmnopqrstuvwxyz"
|
||||
CharsUpper string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
CharsNumbers string = "0123456789"
|
||||
// !#$%&'()*+,-./:;<=>?@[\]^_{|}~`"
|
||||
CharsSpecials string = "\x21\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x40\x5b\x5c\x5d\x5e\x5f\x7b\x7c\x7d\x7e\x60\x22"
|
||||
)
|
||||
|
||||
const (
|
||||
argonMemory uint32 = 128 * 1024 // KiB
|
||||
argonIters uint32 = 24
|
||||
argonThreads uint8 = 3
|
||||
)
|
||||
|
||||
type Params struct {
|
||||
PrivKey []byte
|
||||
Salt []byte
|
||||
Counter []byte // Actually it is a part of argon salt so let it be the same type
|
||||
PassLength uint32
|
||||
UseLower bool
|
||||
UseUpper bool
|
||||
UseNumber bool
|
||||
UseSpecials bool
|
||||
}
|
||||
|
||||
func (p *Params) GeneratePassword() (string, error) {
|
||||
// TODO: Check PassLength <= MAX_UINT32/8
|
||||
|
||||
if !(g.UseLower && p.UseUpper && p.UseNumbers && p.UseSpecials) {
|
||||
return nil, error.New("Use at least one character group.") // CHECK ERROR DECLARATION
|
||||
}
|
||||
if p.UseLower {
|
||||
charSet += charsLower
|
||||
}
|
||||
if p.UseUpper {
|
||||
charSet += charsUpper
|
||||
}
|
||||
if p.UseNumbers {
|
||||
charSet += charsNumbers
|
||||
}
|
||||
if p.UseSpecials {
|
||||
charSet += charsSpecials
|
||||
}
|
||||
|
||||
dkey := argon2.IDKey(p.PrivKey, append(p.Counter, p.Salt), argonIters, argonMemory, argonThreads, p.PassLength*8)
|
||||
|
||||
password := ""
|
||||
for cn := 0; cn < len(dkey); cn += 8 {
|
||||
password += string(charSet[binary.BigEndian.Uint64(dkey[cn:cn+8])%uint64(len(charSet))])
|
||||
}
|
||||
|
||||
return password, nil
|
||||
}
|
75
src/main.go
Normal file
75
src/main.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/KawaiDesu/gaspass/gaspass"
|
||||
"github.com/chzyer/readline"
|
||||
flags "github.com/jessevdk/go-flags"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Resource struct {
|
||||
PassLen int
|
||||
Serial int
|
||||
Host string
|
||||
}
|
||||
|
||||
func checkOpts() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func processFlags() {
|
||||
_, err := flags.Parse(&opts)
|
||||
if flags.WroteHelp(err) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
opts struct {
|
||||
CharsLower bool `short:"l" long:"lower" description:"Use lower-case characters for generating password"`
|
||||
CharsUpper bool `short:"u" long:"upper" description:"Use upper-case characters for generating password"`
|
||||
CharsNumbers bool `short:"n" long:"numeric" description:"Use numeric characters for generating password"`
|
||||
CharsSpecials bool `short:"s" long:"specials" description:"Use speacial (punctuation) characters for generating password"`
|
||||
Length int `short:"q" long:"quantity" default:"16" description:"Set number of characters in the password"`
|
||||
Salt string `short:"r" long:"resource" description:"Resource name (url or some descriptive text) for which password will be generated"`
|
||||
Counter string `short:"c" long:"counter" default:"0" description:"Serial number of the password for the same resource"`
|
||||
ActionAdd bool `short:"A" long:"add" description:"Add resource record to the database"`
|
||||
ActionRemove bool `short:"D" long:"delete" description:"Remove resource record from the database"`
|
||||
ActionUseRes bool `short:"R" long:"use-resource" description:"Use existing resource"`
|
||||
ActionList bool `short:"L" long:"list" description:"List resource records in the database"`
|
||||
ActionBench bool `short:"B" long:"bench" description:"Run benchmark"`
|
||||
}
|
||||
|
||||
charSet string = ""
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
processFlags()
|
||||
|
||||
privKey, err := readline.Password("Enter your key:")
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
p := gaspass.Params{
|
||||
PrivKey: privKey,
|
||||
Salt: []byte(opts.Salt),
|
||||
Counter: []byte(opts.Counter),
|
||||
PassLength: opts.Length,
|
||||
UseLower: opts.CharsLower,
|
||||
UseUpper: opts.CharsUpper,
|
||||
UseNumber: opts.CharsNumbers,
|
||||
UseSpecials: opts.CharsSpecials,
|
||||
}
|
||||
|
||||
resultPass, err := p.GeneratePassword()
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(resultPass)
|
||||
}
|
11
src/sometest.goo
Normal file
11
src/sometest.goo
Normal file
@@ -0,0 +1,11 @@
|
||||
package gaspass
|
||||
/*
|
||||
import "fmt"
|
||||
|
||||
func ExampleGeneratePassword(){
|
||||
fmt.Println(GeneratePassword([]byte("asdfghjkl123")))
|
||||
// Output:
|
||||
// `wPW`9'Ep$JH,@:7
|
||||
|
||||
}
|
||||
*/
|
Reference in New Issue
Block a user