Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2012 The Go Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style | |
3 // license that can be found in the LICENSE file. | |
4 | |
5 package cipher_test | |
6 | |
7 import ( | |
8 "crypto/aes" | |
9 "crypto/cipher" | |
10 "crypto/rand" | |
11 "errors" | |
12 "io" | |
13 "os" | |
14 ) | |
15 | |
16 func ExampleNewCBCDecrypter(key, ciphertext []byte) ([]byte, error) { | |
minux1
2012/10/08 19:38:12
example functions can't take arguments.
agl1
2012/10/08 19:42:23
Although the arguments don't appear in the example
adg
2012/10/12 01:41:55
If you have actual key, ciphertext, and plaintext
| |
17 block, err := aes.NewCipher(key) | |
18 if err != nil { | |
19 return nil, err | |
20 } | |
21 | |
22 // The IV needs to be unique, but not secure. Therefore it's common to | |
23 // include it at the beginning of the ciphertext. | |
24 if len(ciphertext) < aes.BlockSize { | |
25 return nil, errors.New("ciphertext too short") | |
26 } | |
27 iv := ciphertext[:aes.BlockSize] | |
28 ciphertext = ciphertext[aes.BlockSize:] | |
29 | |
30 // CBC mode always works in whole blocks. | |
31 if len(ciphertext)%aes.BlockSize != 0 { | |
32 return nil, errors.New("ciphertext is not a multiple of the bloc k size") | |
33 } | |
34 | |
35 mode := cipher.NewCBCDecrypter(block, iv) | |
36 | |
37 // CryptBlocks can work in-place if the two arguments are the same. | |
38 mode.CryptBlocks(ciphertext, ciphertext) | |
39 | |
40 // If the original plaintext lengths are not a multiple of the block | |
41 // size, padding would have to be added when encrypting, which would be | |
42 // removed at this point. For an example, see | |
43 // https://tools.ietf.org/html/rfc5246#section-6.2.3.2. However, it's | |
44 // critical to note that ciphertexts must be authenticated (i.e. by | |
45 // using crypto/hmac) before being decrypted in order to avoid creating | |
46 // a padding oracle. | |
47 | |
48 return ciphertext, nil | |
49 } | |
50 | |
51 func ExampleNewCBCEncrypter(key, plaintext []byte) ([]byte, error) { | |
52 // CBC mode works on blocks so plaintexts may need to be padded to the | |
53 // next whole block. For an example of such padding, see | |
54 // https://tools.ietf.org/html/rfc5246#section-6.2.3.2. Here we'll | |
55 // assume that the plaintext is already of the correct length. | |
56 if len(plaintext)%aes.BlockSize != 0 { | |
57 return nil, errors.New("plaintext is not a multiple of the block size") | |
58 } | |
59 | |
60 block, err := aes.NewCipher(key) | |
61 if err != nil { | |
62 return nil, err | |
63 } | |
64 | |
65 // The IV needs to be unique, but not secure. Therefore it's common to | |
66 // include it at the beginning of the ciphertext. | |
67 ciphertext := make([]byte, aes.BlockSize+len(plaintext)) | |
68 iv := ciphertext[:aes.BlockSize] | |
69 if _, err := io.ReadFull(rand.Reader, iv); err != nil { | |
70 return nil, err | |
71 } | |
72 | |
73 mode := cipher.NewCBCEncrypter(block, iv) | |
74 mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext) | |
75 | |
76 // It's important to remember that ciphertexts must be authenticated | |
77 // (i.e. by using crypto/hmac) as well as being encrypted in order to | |
78 // be secure. | |
79 | |
80 return ciphertext, nil | |
81 } | |
82 | |
83 func ExampleNewCFBDecrypter(key, ciphertext []byte) ([]byte, error) { | |
84 block, err := aes.NewCipher(key) | |
85 if err != nil { | |
86 return nil, err | |
87 } | |
88 | |
89 // The IV needs to be unique, but not secure. Therefore it's common to | |
90 // include it at the beginning of the ciphertext. | |
91 if len(ciphertext) < aes.BlockSize { | |
92 return nil, errors.New("ciphertext too short") | |
93 } | |
94 iv := ciphertext[:aes.BlockSize] | |
95 ciphertext = ciphertext[aes.BlockSize:] | |
96 | |
97 stream := cipher.NewCFBDecrypter(block, iv) | |
98 | |
99 // XORKeyStream can work in-place if the two arguments are the same. | |
100 stream.XORKeyStream(ciphertext, ciphertext) | |
101 return ciphertext, nil | |
102 } | |
103 | |
104 func ExampleNewCFBEncrypter(key, plaintext []byte) ([]byte, error) { | |
105 block, err := aes.NewCipher(key) | |
106 if err != nil { | |
107 return nil, err | |
108 } | |
109 | |
110 // The IV needs to be unique, but not secure. Therefore it's common to | |
111 // include it at the beginning of the ciphertext. | |
112 ciphertext := make([]byte, aes.BlockSize+len(plaintext)) | |
113 iv := ciphertext[:aes.BlockSize] | |
114 if _, err := io.ReadFull(rand.Reader, iv); err != nil { | |
115 return nil, err | |
116 } | |
117 | |
118 stream := cipher.NewCFBEncrypter(block, iv) | |
119 stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext) | |
120 | |
121 // It's important to remember that ciphertexts must be authenticated | |
122 // (i.e. by using crypto/hmac) as well as being encrypted in order to | |
123 // be secure. | |
124 | |
125 return ciphertext, nil | |
126 } | |
127 | |
128 func ExampleNewCTR(key, plaintext []byte) error { | |
129 block, err := aes.NewCipher(key) | |
130 if err != nil { | |
131 return err | |
132 } | |
133 | |
134 // The IV needs to be unique, but not secure. Therefore it's common to | |
135 // include it at the beginning of the ciphertext. | |
136 ciphertext := make([]byte, aes.BlockSize+len(plaintext)) | |
137 iv := ciphertext[:aes.BlockSize] | |
138 if _, err := io.ReadFull(rand.Reader, iv); err != nil { | |
139 return err | |
140 } | |
141 | |
142 stream := cipher.NewCTR(block, iv) | |
143 stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext) | |
144 | |
145 // It's important to remember that ciphertexts must be authenticated | |
146 // (i.e. by using crypto/hmac) as well as being encrypted in order to | |
147 // be secure. | |
148 | |
149 // CTR mode is the same for both encryption and decryption, so we can | |
150 // also decrypt that ciphertext with NewCTR. | |
151 | |
152 plaintext2 := make([]byte, len(plaintext)) | |
153 stream = cipher.NewCTR(block, iv) | |
154 stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:]) | |
155 | |
156 return nil | |
157 } | |
158 | |
159 func ExampleNewOFB(key, plaintext []byte) error { | |
160 block, err := aes.NewCipher(key) | |
161 if err != nil { | |
162 return err | |
163 } | |
164 | |
165 // The IV needs to be unique, but not secure. Therefore it's common to | |
166 // include it at the beginning of the ciphertext. | |
167 ciphertext := make([]byte, aes.BlockSize+len(plaintext)) | |
168 iv := ciphertext[:aes.BlockSize] | |
169 if _, err := io.ReadFull(rand.Reader, iv); err != nil { | |
170 return err | |
171 } | |
172 | |
173 stream := cipher.NewOFB(block, iv) | |
174 stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext) | |
175 | |
176 // It's important to remember that ciphertexts must be authenticated | |
177 // (i.e. by using crypto/hmac) as well as being encrypted in order to | |
178 // be secure. | |
179 | |
180 // OFB mode is the same for both encryption and decryption, so we can | |
181 // also decrypt that ciphertext with NewOFB. | |
182 | |
183 plaintext2 := make([]byte, len(plaintext)) | |
184 stream = cipher.NewOFB(block, iv) | |
185 stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:]) | |
186 | |
187 return nil | |
188 } | |
189 | |
190 func ExampleStreamReader(key []byte) error { | |
191 inFile, err := os.Open("encrypted-file") | |
192 if err != nil { | |
193 return err | |
194 } | |
195 defer inFile.Close() | |
196 | |
197 block, err := aes.NewCipher(key) | |
198 if err != nil { | |
199 return err | |
200 } | |
201 | |
202 // If the key is unique for each ciphertext, then it's ok to use a zero | |
203 // IV. | |
204 var iv [aes.BlockSize]byte | |
205 stream := cipher.NewOFB(block, iv[:]) | |
206 | |
207 outFile, err := os.OpenFile("decrypted-file", os.O_WRONLY|os.O_CREATE|os .O_TRUNC, 0600) | |
208 if err != nil { | |
209 return err | |
210 } | |
211 defer outFile.Close() | |
212 | |
213 reader := &cipher.StreamReader{stream, inFile} | |
214 // Copy the input file to the output file, decrypting as we go. | |
215 if _, err := io.Copy(outFile, reader); err != nil { | |
216 return err | |
217 } | |
218 | |
219 // Note that this example is simplistic in that it omits any | |
220 // authentication of the encrypted data. It you were actually to use | |
221 // StreamReader in this manner, an attacker could flip arbitary bits in | |
222 // the output. | |
223 | |
224 return nil | |
225 } | |
226 | |
227 func ExampleStreamWriter(key []byte) error { | |
228 inFile, err := os.Open("plaintext-file") | |
229 if err != nil { | |
230 return err | |
231 } | |
232 defer inFile.Close() | |
233 | |
234 block, err := aes.NewCipher(key) | |
235 if err != nil { | |
236 return err | |
237 } | |
238 | |
239 // If the key is unique for each ciphertext, then it's ok to use a zero | |
240 // IV. | |
241 var iv [aes.BlockSize]byte | |
242 stream := cipher.NewOFB(block, iv[:]) | |
243 | |
244 outFile, err := os.OpenFile("encrypted-file", os.O_WRONLY|os.O_CREATE|os .O_TRUNC, 0600) | |
245 if err != nil { | |
246 return err | |
247 } | |
248 defer outFile.Close() | |
249 | |
250 writer := &cipher.StreamWriter{stream, outFile, nil} | |
251 // Copy the input file to the output file, encrypting as we go. | |
252 if _, err := io.Copy(writer, inFile); err != nil { | |
253 return err | |
254 } | |
255 | |
256 // Note that this example is simplistic in that it omits any | |
257 // authentication of the encrypted data. It you were actually to use | |
258 // StreamReader in this manner, an attacker could flip arbitary bits in | |
259 // the decrypted result. | |
260 | |
261 return nil | |
262 } | |
OLD | NEW |