128 lines
3.2 KiB
Go
128 lines
3.2 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"crypto"
|
||
|
"crypto/aes"
|
||
|
"crypto/cipher"
|
||
|
"crypto/ed25519"
|
||
|
"encoding/hex"
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/dchest/bcrypt_pbkdf"
|
||
|
)
|
||
|
|
||
|
/*
|
||
|
Same key as private.ed25519 example.
|
||
|
*/
|
||
|
|
||
|
func main() {
|
||
|
const (
|
||
|
passphrase string = "test"
|
||
|
rounds int = 100
|
||
|
keySize int = 32
|
||
|
lenPlain int = 160
|
||
|
)
|
||
|
var salt []byte
|
||
|
var bcryptKey []byte
|
||
|
var sk []byte
|
||
|
var pk []byte
|
||
|
var pubkey crypto.PublicKey
|
||
|
var key ed25519.PrivateKey
|
||
|
var decrypted []byte
|
||
|
var aesCtx cipher.Block
|
||
|
var encData []byte
|
||
|
|
||
|
decrypted = make([]byte, lenPlain)
|
||
|
encData = make([]byte, lenPlain)
|
||
|
|
||
|
// Import salt
|
||
|
if s, err := hex.DecodeString("50132f72900d68e0a31f9d75b6f0a5bc"); err != nil {
|
||
|
fmt.Println(err)
|
||
|
return
|
||
|
} else {
|
||
|
salt = s
|
||
|
}
|
||
|
|
||
|
// Import encrypted data
|
||
|
if b, err := hex.DecodeString(
|
||
|
"c49777cd0d1a7d37db77a1814991278f8ce99d572e2c666b93b99867425c60da" +
|
||
|
"4652fddb8555098532b51beeee2959f9db5cf5a0905052720c5de25f2c4dd87e" +
|
||
|
"bcc7bb5ea3d7bcbeacc6b732e4c39295d9991a97ef3f0838f8a9bfd43edb3403" +
|
||
|
"189649088f6cfb78946fb914e358ac6abc64691072f5f2788534d9d42d7f406b" +
|
||
|
"c5090b30df23cb7dd8c5cb938e41facd6e38e8845b8160bff840598118d447c2",
|
||
|
); err != nil {
|
||
|
fmt.Println(err)
|
||
|
return
|
||
|
} else {
|
||
|
encData = b
|
||
|
}
|
||
|
|
||
|
// ED25519 keys
|
||
|
// This is used to validate decrypted keys.
|
||
|
if edk, err := hex.DecodeString(
|
||
|
"ce6e2b8d638c9d5219dff455af1a90d0a5b72694cfcedfb93bc1e1b1816dee98" +
|
||
|
"bfa2031aa5463113e40e16896af503c5299ead76b09cb63846f41cc4de1740f6",
|
||
|
); err != nil {
|
||
|
fmt.Println(err)
|
||
|
return
|
||
|
} else {
|
||
|
key = edk
|
||
|
// .Public() returns a crypto.PublicKey, which... is an interface that seemingly cannot be type asserted to anything.
|
||
|
pubkey = key.Public()
|
||
|
}
|
||
|
sep := len(key) - ed25519.PublicKeySize
|
||
|
pk = key[sep:]
|
||
|
sk = key[0:sep]
|
||
|
|
||
|
// Bcrypt_pbkdf2 derivation (used for deriving decryption key for AES encrypted private key)
|
||
|
// if k, err := bcrypt_pbkdf.Key([]byte(passphrase), salt, rounds, keySize); err != nil {
|
||
|
if k, err := bcrypt_pbkdf.Key([]byte(passphrase), salt, rounds, keySize+len(salt)); err != nil {
|
||
|
fmt.Println(err)
|
||
|
return
|
||
|
} else {
|
||
|
bcryptKey = k
|
||
|
}
|
||
|
realBcryptKey := bcryptKey[0:sep]
|
||
|
realIV := bcryptKey[sep:]
|
||
|
|
||
|
// Decrypter
|
||
|
if a, err := aes.NewCipher(realBcryptKey); err != nil {
|
||
|
fmt.Println(err)
|
||
|
return
|
||
|
} else {
|
||
|
aesCtx = a
|
||
|
}
|
||
|
|
||
|
// Actual cipher setup. AES256-CBC
|
||
|
// d := cipher.NewCBCDecrypter(aesCtx, realIV)
|
||
|
// d.CryptBlocks(decrypted, encData)
|
||
|
|
||
|
// Actual cipher setup. AES256-CTR
|
||
|
d := cipher.NewCTR(aesCtx, realIV)
|
||
|
d.XORKeyStream(decrypted, encData)
|
||
|
|
||
|
/*
|
||
|
if p, s, err := ed25519.GenerateKey(nil); err != nil {
|
||
|
fmt.Println(err)
|
||
|
return
|
||
|
} else {
|
||
|
pubkey = p
|
||
|
key = s
|
||
|
pk = key[(len(key) - ed25519.PublicKeySize):]
|
||
|
sk = key[0:(len(key) - ed25519.PublicKeySize)]
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
fmt.Printf("ED25519 key: %v\n", hex.EncodeToString(key))
|
||
|
fmt.Printf("Pubkey: %v\n", pubkey)
|
||
|
fmt.Printf("SK: %v\n", hex.EncodeToString(sk))
|
||
|
fmt.Printf("PK: %v\n", hex.EncodeToString(pk))
|
||
|
fmt.Printf("Salt: %v\n", hex.EncodeToString(salt))
|
||
|
fmt.Printf("Bcrypt Key: %v\n", hex.EncodeToString(bcryptKey))
|
||
|
fmt.Printf("realBcryptKey: %v\n", hex.EncodeToString(realBcryptKey))
|
||
|
fmt.Printf("realIV: %v\n", hex.EncodeToString(realIV))
|
||
|
// fmt.Printf("Encrypted data: %v\n", hex.EncodeToString(encData))
|
||
|
fmt.Printf("Decrypted data?: %v\n", hex.EncodeToString(decrypted))
|
||
|
|
||
|
}
|