/
crypto.go
102 lines (92 loc) · 3.3 KB
/
crypto.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package common
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/des"
"github.com/andreburgaud/crypt2go/ecb"
)
// DesEcbEncrypt encrypts the plain text with PKCS #7 padding and
// electronic codebook mode of operation.
func DesEcbEncrypt(plainText, key []byte) (cipherText []byte) {
block, err := des.NewCipher(key)
Must(err)
plainText = PKCS7Padding(plainText, len(key))
cipherText = make([]byte, len(plainText))
blockMode := ecb.NewECBEncrypter(block)
blockMode.CryptBlocks(cipherText, plainText)
return
}
// DesEcbDecrypt is the counterpart of DesEcbEncrypt; it decrypts the cipher
// text and strips the PKCS #7 padding bytes off the end of the plain text.
func DesEcbDecrypt(cipherText, key []byte) (plainText []byte) {
block, err := des.NewCipher(key)
Must(err)
plainText = make([]byte, len(cipherText))
blockMode := ecb.NewECBDecrypter(block)
blockMode.CryptBlocks(plainText, cipherText)
return PKCS7Unpadding(plainText)
}
// AesEcbEncrypt encrypts the plain text with PKCS #7 padding and
// electronic codebook mode of operation.
func AesEcbEncrypt(plainText, key []byte) (cipherText []byte) {
block, err := aes.NewCipher(key)
Must(err)
plainText = PKCS7Padding(plainText, len(key))
cipherText = make([]byte, len(plainText))
blockMode := ecb.NewECBEncrypter(block)
blockMode.CryptBlocks(cipherText, plainText)
return
}
// AesEcbDecrypt is the counterpart of AesEcbEncrypt; it decrypts the cipher
// text and strips the PKCS #7 padding bytes off the end of the plain text.
func AesEcbDecrypt(cipherText, key []byte) (plainText []byte) {
block, err := aes.NewCipher(key)
Must(err)
plainText = make([]byte, len(cipherText))
blockMode := ecb.NewECBDecrypter(block)
blockMode.CryptBlocks(plainText, cipherText)
return PKCS7Unpadding(plainText)
}
// AesCbcEncrypt encrypts the plain text with PKCS #7 padding, block chaining
// mode of operation, and a predefined initial vector.
func AesCbcEncrypt(plainText, key, iv []byte) (cipherText []byte) {
block, err := aes.NewCipher(key)
Must(err)
plainText = PKCS7Padding(plainText, len(iv))
cipherText = make([]byte, len(plainText))
blockMode := cipher.NewCBCEncrypter(block, iv)
blockMode.CryptBlocks(cipherText, plainText)
return
}
// AesCbcDecrypt is the counterpart of AesCbcEncrypt; it decrypts the cipher
// text and strips the PKCS #7 padding bytes off the end of the plain text.
func AesCbcDecrypt(cipherText, key, iv []byte) (plainText []byte) {
block, err := aes.NewCipher(key)
Must(err)
plainText = make([]byte, len(cipherText))
blockMode := cipher.NewCBCDecrypter(block, iv)
blockMode.CryptBlocks(plainText, cipherText)
return PKCS7Unpadding(plainText)
}
// PKCS7Padding pads the input octet vector to a multiple of blockSize octets
// with the scheme defined in RFC 2315.
func PKCS7Padding(input []byte, blockSize int) (buf []byte) {
if len(input) == 0 || blockSize < 1 || blockSize > 255 {
return
}
pad := blockSize - len(input)%blockSize
buf = make([]byte, len(input)+pad)
copy(buf, input)
copy(buf[len(input):], bytes.Repeat([]byte{byte(pad)}, pad))
return
}
// PKCS7Unpadding removes the padded bytes from the decrypted text
// according to the last decrypted byte to recover the original payload.
func PKCS7Unpadding(padded []byte) []byte {
length := len(padded)
if length == 0 {
return nil
}
return padded[:length-int(padded[length-1])]
}