Exemplo n.º 1
0
func (ks keyStorePassphrase) StoreKey(key *Key, auth string) (err error) {
	authArray := []byte(auth)
	salt := randentropy.GetEntropyMixed(32)
	derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptr, scryptp, scryptdkLen)
	if err != nil {
		return err
	}

	keyBytes := key.PrivateKey
	toEncrypt := util.PKCS7Pad(keyBytes)

	AES256Block, err := aes.NewCipher(derivedKey)
	if err != nil {
		return err
	}

	gcm, err := cipher.NewGCM(AES256Block)
	if err != nil {
		return err
	}

	// XXX: a GCM nonce may only be used once per key ever!
	nonce := randentropy.GetEntropyMixed(gcm.NonceSize())

	// (dst, nonce, plaintext, extradata)
	cipherText := gcm.Seal(nil, nonce, toEncrypt, nil)

	cipherStruct := cipherJSON{
		salt,
		nonce,
		cipherText,
	}
	keyStruct := encryptedKeyJSON{
		key.Id,
		key.Type.String(),
		strings.ToUpper(hex.EncodeToString(key.Address)),
		cipherStruct,
	}
	keyJSON, err := json.Marshal(keyStruct)
	if err != nil {
		return err
	}

	return WriteKeyFile(key.Address, ks.keysDirPath, keyJSON)
}
Exemplo n.º 2
0
func DecryptKey(ks keyStorePassphrase, keyAddr []byte, auth string) (*Key, error) {
	fileContent, err := GetKeyFile(ks.keysDirPath, keyAddr)
	if err != nil {
		return nil, err
	}

	keyProtected := new(encryptedKeyJSON)
	if err = json.Unmarshal(fileContent, keyProtected); err != nil {
		return nil, err
	}

	keyId := keyProtected.Id
	keyType, err := KeyTypeFromString(keyProtected.Type)
	if err != nil {
		return nil, err
	}

	keyAddr2, err := hex.DecodeString(keyProtected.Address)
	if bytes.Compare(keyAddr, keyAddr2) != 0 {
		return nil, fmt.Errorf("address of key and address in file do not match. Got %x, expected %x", keyAddr2, keyAddr)
	}
	salt := keyProtected.Crypto.Salt
	nonce := keyProtected.Crypto.Nonce
	cipherText := keyProtected.Crypto.CipherText

	authArray := []byte(auth)
	derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptr, scryptp, scryptdkLen)
	if err != nil {
		return nil, err
	}
	plainText, err := aesGCMDecrypt(derivedKey, cipherText, nonce)
	if err != nil {
		return nil, err
	}

	// no need to use a checksum as done by gcm

	return &Key{
		Id:         uuid.UUID(keyId),
		Type:       keyType,
		Address:    keyAddr,
		PrivateKey: plainText,
	}, nil
}