mirror of
https://github.com/octoleo/restic.git
synced 2024-11-24 21:57:41 +00:00
Use CTR instead of CBC for encryption
This commit is contained in:
parent
f37d0bf45f
commit
58f7b1be1e
53
key.go
53
key.go
@ -1,7 +1,6 @@
|
||||
package khepri
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/hmac"
|
||||
@ -231,40 +230,6 @@ func (k *Key) newIV() ([]byte, error) {
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func (k *Key) pad(plaintext []byte) []byte {
|
||||
l := aes.BlockSize - (len(plaintext) % aes.BlockSize)
|
||||
if l == 0 {
|
||||
l = aes.BlockSize
|
||||
}
|
||||
|
||||
if l <= 0 || l > aes.BlockSize {
|
||||
panic("invalid padding size")
|
||||
}
|
||||
|
||||
return append(plaintext, bytes.Repeat([]byte{byte(l)}, l)...)
|
||||
}
|
||||
|
||||
func (k *Key) unpad(plaintext []byte) []byte {
|
||||
l := len(plaintext)
|
||||
pad := plaintext[l-1]
|
||||
|
||||
if pad > aes.BlockSize {
|
||||
panic(errors.New("padding > BlockSize"))
|
||||
}
|
||||
|
||||
if pad == 0 {
|
||||
panic(errors.New("invalid padding 0"))
|
||||
}
|
||||
|
||||
for i := l - int(pad); i < l; i++ {
|
||||
if plaintext[i] != pad {
|
||||
panic(errors.New("invalid padding!"))
|
||||
}
|
||||
}
|
||||
|
||||
return plaintext[:l-int(pad)]
|
||||
}
|
||||
|
||||
// Encrypt encrypts and signs data. Returned is IV || Ciphertext || HMAC. For
|
||||
// the hash function, SHA256 is used, so the overhead is 16+32=48 byte.
|
||||
func (k *Key) encrypt(ks *keys, plaintext []byte) ([]byte, error) {
|
||||
@ -278,12 +243,11 @@ func (k *Key) encrypt(ks *keys, plaintext []byte) ([]byte, error) {
|
||||
panic(fmt.Sprintf("unable to create cipher: %v", err))
|
||||
}
|
||||
|
||||
e := cipher.NewCBCEncrypter(c, iv)
|
||||
p := k.pad(plaintext)
|
||||
ciphertext := make([]byte, len(p))
|
||||
e.CryptBlocks(ciphertext, p)
|
||||
|
||||
ciphertext = append(iv, ciphertext...)
|
||||
e := cipher.NewCTR(c, iv)
|
||||
l := len(iv)
|
||||
ciphertext := make([]byte, l+len(plaintext))
|
||||
copy(ciphertext[:l], iv)
|
||||
e.XORKeyStream(ciphertext[l:], plaintext)
|
||||
|
||||
hm := hmac.New(sha256.New, ks.Sign)
|
||||
|
||||
@ -341,12 +305,11 @@ func (k *Key) decrypt(ks *keys, ciphertext []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
// decrypt
|
||||
e := cipher.NewCBCDecrypter(c, iv)
|
||||
e := cipher.NewCTR(c, iv)
|
||||
plaintext := make([]byte, len(ciphertext))
|
||||
e.CryptBlocks(plaintext, ciphertext)
|
||||
e.XORKeyStream(plaintext, ciphertext)
|
||||
|
||||
// remove padding and return
|
||||
return k.unpad(plaintext), nil
|
||||
return plaintext, nil
|
||||
}
|
||||
|
||||
// Decrypt verifes and decrypts the ciphertext with the master key. Ciphertext
|
||||
|
@ -15,7 +15,7 @@ var test_values = []struct {
|
||||
{
|
||||
ekey: decode_hex("303e8687b1d7db18421bdc6bb8588ccadac4d59ee87b8ff70c44e635790cafef"),
|
||||
skey: decode_hex("cc8d4b948ee0ebfe1d415de921d10353ef4d8824cb80b2bcc5fbff8a9b12a42c"),
|
||||
ciphertext: decode_hex("154f582d77e6430409da392c3a09aa38e00a78bcc8919557fe18dd17f83e7b0b3053def59f4215b6e1c6b72ceb5acdddd8511ce3a853e054218de1e9f34637470d68f1f93ba8228e4d9817d7c9acfcd2"),
|
||||
ciphertext: decode_hex("fe85b32b108308f6f8834a96e463b66e0eae6a0f1e9809da0773a2db12a24528bce3220e6a5700b40bd45ef2a2ce96a7fc0a895a019d4a77eef5fc9579297059c6d0"),
|
||||
plaintext: []byte("Dies ist ein Test!"),
|
||||
},
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user