Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(100)

Side by Side Diff: src/pkg/crypto/cipher/example_test.go

Issue 6631044: code review 6631044: crypto/cipher: add examples (Closed)
Patch Set: diff -r cfbcf8176d26 https://go.googlecode.com/hg/ Created 11 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b