1/*-
2 * Copyright 2014 Square Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package jose
18
19import (
20	"crypto/ecdsa"
21	"crypto/rand"
22	"crypto/rsa"
23	"fmt"
24)
25
26// Dummy encrypter for use in examples
27var encrypter Encrypter
28
29func Example_jWE() {
30	// Generate a public/private key pair to use for this example.
31	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
32	if err != nil {
33		panic(err)
34	}
35
36	// Instantiate an encrypter using RSA-OAEP with AES128-GCM. An error would
37	// indicate that the selected algorithm(s) are not currently supported.
38	publicKey := &privateKey.PublicKey
39	encrypter, err := NewEncrypter(A128GCM, Recipient{Algorithm: RSA_OAEP, Key: publicKey}, nil)
40	if err != nil {
41		panic(err)
42	}
43
44	// Encrypt a sample plaintext. Calling the encrypter returns an encrypted
45	// JWE object, which can then be serialized for output afterwards. An error
46	// would indicate a problem in an underlying cryptographic primitive.
47	var plaintext = []byte("Lorem ipsum dolor sit amet")
48	object, err := encrypter.Encrypt(plaintext)
49	if err != nil {
50		panic(err)
51	}
52
53	// Serialize the encrypted object using the full serialization format.
54	// Alternatively you can also use the compact format here by calling
55	// object.CompactSerialize() instead.
56	serialized := object.FullSerialize()
57
58	// Parse the serialized, encrypted JWE object. An error would indicate that
59	// the given input did not represent a valid message.
60	object, err = ParseEncrypted(serialized)
61	if err != nil {
62		panic(err)
63	}
64
65	// Now we can decrypt and get back our original plaintext. An error here
66	// would indicate the the message failed to decrypt, e.g. because the auth
67	// tag was broken or the message was tampered with.
68	decrypted, err := object.Decrypt(privateKey)
69	if err != nil {
70		panic(err)
71	}
72
73	fmt.Printf(string(decrypted))
74	// output: Lorem ipsum dolor sit amet
75}
76
77func Example_jWS() {
78	// Generate a public/private key pair to use for this example.
79	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
80	if err != nil {
81		panic(err)
82	}
83
84	// Instantiate a signer using RSASSA-PSS (SHA512) with the given private key.
85	signer, err := NewSigner(SigningKey{Algorithm: PS512, Key: privateKey}, nil)
86	if err != nil {
87		panic(err)
88	}
89
90	// Sign a sample payload. Calling the signer returns a protected JWS object,
91	// which can then be serialized for output afterwards. An error would
92	// indicate a problem in an underlying cryptographic primitive.
93	var payload = []byte("Lorem ipsum dolor sit amet")
94	object, err := signer.Sign(payload)
95	if err != nil {
96		panic(err)
97	}
98
99	// Serialize the encrypted object using the full serialization format.
100	// Alternatively you can also use the compact format here by calling
101	// object.CompactSerialize() instead.
102	serialized := object.FullSerialize()
103
104	// Parse the serialized, protected JWS object. An error would indicate that
105	// the given input did not represent a valid message.
106	object, err = ParseSigned(serialized)
107	if err != nil {
108		panic(err)
109	}
110
111	// Now we can verify the signature on the payload. An error here would
112	// indicate the the message failed to verify, e.g. because the signature was
113	// broken or the message was tampered with.
114	output, err := object.Verify(&privateKey.PublicKey)
115	if err != nil {
116		panic(err)
117	}
118
119	fmt.Printf(string(output))
120	// output: Lorem ipsum dolor sit amet
121}
122
123func ExampleNewEncrypter_publicKey() {
124	var publicKey *rsa.PublicKey
125
126	// Instantiate an encrypter using RSA-OAEP with AES128-GCM.
127	NewEncrypter(A128GCM, Recipient{Algorithm: RSA_OAEP, Key: publicKey}, nil)
128
129	// Instantiate an encrypter using RSA-PKCS1v1.5 with AES128-CBC+HMAC.
130	NewEncrypter(A128CBC_HS256, Recipient{Algorithm: RSA1_5, Key: publicKey}, nil)
131}
132
133func ExampleNewEncrypter_symmetric() {
134	var sharedKey []byte
135
136	// Instantiate an encrypter using AES128-GCM with AES-GCM key wrap.
137	NewEncrypter(A128GCM, Recipient{Algorithm: A128GCMKW, Key: sharedKey}, nil)
138
139	// Instantiate an encrypter using AES128-GCM directly, w/o key wrapping.
140	NewEncrypter(A128GCM, Recipient{Algorithm: DIRECT, Key: sharedKey}, nil)
141}
142
143func ExampleNewSigner_publicKey() {
144	var rsaPrivateKey *rsa.PrivateKey
145	var ecdsaPrivateKey *ecdsa.PrivateKey
146
147	// Instantiate a signer using RSA-PKCS#1v1.5 with SHA-256.
148	NewSigner(SigningKey{Algorithm: RS256, Key: rsaPrivateKey}, nil)
149
150	// Instantiate a signer using ECDSA with SHA-384.
151	NewSigner(SigningKey{Algorithm: ES384, Key: ecdsaPrivateKey}, nil)
152}
153
154func ExampleNewSigner_symmetric() {
155	var sharedKey []byte
156
157	// Instantiate an signer using HMAC-SHA256.
158	NewSigner(SigningKey{Algorithm: HS256, Key: sharedKey}, nil)
159
160	// Instantiate an signer using HMAC-SHA512.
161	NewSigner(SigningKey{Algorithm: HS512, Key: sharedKey}, nil)
162}
163
164func ExampleNewMultiEncrypter() {
165	var publicKey *rsa.PublicKey
166	var sharedKey []byte
167
168	// Instantiate an encrypter using AES-GCM.
169	NewMultiEncrypter(A128GCM, []Recipient{
170		{Algorithm: A128GCMKW, Key: sharedKey},
171		{Algorithm: RSA_OAEP, Key: publicKey},
172	}, nil)
173}
174
175func ExampleNewMultiSigner() {
176	var privateKey *rsa.PrivateKey
177	var sharedKey []byte
178
179	// Instantiate a signer for multiple recipients.
180	NewMultiSigner([]SigningKey{
181		{Algorithm: HS256, Key: sharedKey},
182		{Algorithm: PS384, Key: privateKey},
183	}, nil)
184}
185
186func ExampleEncrypter_encrypt() {
187	// Encrypt a plaintext in order to get an encrypted JWE object.
188	var plaintext = []byte("This is a secret message")
189
190	encrypter.Encrypt(plaintext)
191}
192
193func ExampleEncrypter_encryptWithAuthData() {
194	// Encrypt a plaintext in order to get an encrypted JWE object. Also attach
195	// some additional authenticated data (AAD) to the object. Note that objects
196	// with attached AAD can only be represented using full serialization.
197	var plaintext = []byte("This is a secret message")
198	var aad = []byte("This is authenticated, but public data")
199
200	encrypter.EncryptWithAuthData(plaintext, aad)
201}
202