Docs: add general document on how pass phrases are handled
[openssl.git] / doc / man7 / passphrase-encoding.pod
1 =pod
2
3 =encoding utf8
4
5 =head1 NAME
6
7 password encoding
8 - How diverse parts of OpenSSL treat pass phrases character encoding
9
10 =head1 DESCRIPTION
11
12 In a modern world with all sorts of character encodings, the treatment of pass
13 phrases has become increasingly complex.
14 This manual page attempts to give an overview over how this problem is
15 currently addressed in different parts of the OpenSSL library.
16
17 =head2 The general case
18
19 The OpenSSL library doesn't treat pass phrases in any special way as a general
20 rule, and trusts the application or user to choose a suitable character set
21 and stick to that throughout the lifetime of affected objects.
22 This means that for an object that was encrypted using a pass phrase encoded in
23 ISO-8859-1, that object needs to be decrypted using a pass phrase encoded in
24 ISO-8859-1.
25 Using the wrong encoding is expected to cause a decryption failure.
26
27 =head2 PKCS#12
28
29 PKCS#12 is a bit different regarding pass phrase encoding.
30 The standard stipulates that the pass phrase shall be encoded as an ASN.1
31 BMPString, which consists of the code points of the basic multilingual plane,
32 encoded in big endian (UCS-2 BE).
33
34 OpenSSL tries to adapt to this requirements in one of the following manners:
35
36 =over 4
37
38 =item 1.
39
40 Treats the received pass phrase as UTF-8 encoded and tries to re-encode it to
41 UTF-16 (which is the same as UCS-2 for characters U+0000 to U+D7FF and U+E000
42 to U+FFFF, but becomes an expansion for any other character), or failing that,
43 proceeds with step 2.
44
45 =item 2.
46
47 Assumes that the pass phrase is encoded in ASCII or ISO-8859-1 and
48 opportunistically prepends each byte with a zero byte to obtain the UCS-2
49 encoding of the characters, which it stores as a BMPString.
50
51 Note that since there is no check of your locale, this may produce UCS-2 /
52 UTF-16 characters that do not correspond to the original pass phrase characters
53 for other character sets, such as any ISO-8859-X encoding other than
54 ISO-8859-1 (or for Windows, CP 1252 with exception for the extra "graphical"
55 characters in the 0x80-0x9F range).
56
57 =back
58
59 OpenSSL versions older than 1.1.0 do variant 2 only, and that is the reason why
60 OpenSSL still does this, to be able to read files produced with older versions.
61
62 It should be noted that this approach isn't entirely fault free.
63
64 A passphrase encoded in ISO-8859-2 could very well have a sequence such as
65 0xC3 0xAF (which is the two characters "LATIN CAPITAL LETTER A WITH BREVE"
66 and "LATIN CAPITAL LETTER Z WITH DOT ABOVE" in ISO-8859-2 encoding), but would
67 be misinterpreted as the perfectly valid UTF-8 encoded code point U+00EF (LATIN
68 SMALL LETTER I WITH DIARESIS) I<if the passphrase doesn't contain anything that
69 would be invalid UTF-8>.
70 A pass phrase that contains this kind of byte sequence will give a different
71 outcome in OpenSSL 1.1.0 and newer than in OpenSSL older than 1.1.0.
72
73  0x00 0xC3 0x00 0xAF                    # OpenSSL older than 1.1.0
74  0x00 0xEF                              # OpenSSL 1.1.0 and newer
75
76 On the same accord, anything encoded in UTF-8 that was given to OpenSSL older
77 than 1.1.0 was misinterpreted as ISO-8859-1 sequences.
78
79 =head2 OSSL_STORE
80
81 L<ossl_store(7)> acts as a general interface to access all kinds of objects,
82 potentially protected with a pass phrase, a PIN or something else.
83 This API currently doesn't stipulate any specific encoding of pass phrases, but
84 uses the underlying routines with their behaviours.
85 This means that when using the built-in C<file:> scheme loader, the pass phrase
86 to unlock a PKCS#12 file will be treated as described for PKCS#12 above, and
87 the pass phrase for a PEM files will be treated as the general case described
88 above, since that loader uses the same underlying routines.
89 I<Note that other loaders will have their own behaviours>.
90
91 =head1 RECOMMENDATIONS
92
93 This section assumes that you know what pass phrase was used for encryption,
94 but that it may have been encoded in a different character encoding than the
95 one used by your current input method.
96 For example, the pass phrase may have been used at a time when your default
97 encoding was ISO-8859-1 (i.e. "naïve" resulting in the byte sequence 0x6E 0x61
98 0xEF 0x76 0x65), and you're now in an environment where your default encoding
99 is UTF-8 (i.e. "naïve" resulting in the byte sequence 0x6E 0x61 0xC3 0xAF 0x76
100 0x65).
101 Whenever it's mentioned that you should use a certain character encoding, it
102 should be understood that you either change the input method to use the
103 mentioned encoding when you type in your pass phrase, or use some suitable tool
104 to convert your pass phrase from your default encoding to the target encoding.
105
106 Also note that the sub-sections below discuss human readable pass phrases.
107 This is particularly relevant for PKCS#12 objects, where human readable pass
108 phrases are assumed.
109 For other objects, it's as legitimate to use any byte sequence (such as a
110 sequence of bytes from `/dev/urandom` that's been saved away), which makes any
111 character encoding discussion irrelevant; in such cases, simply use the same
112 byte sequence as it is.
113
114 =head2 Creating new objects
115
116 For creating new pass phrase protected objects, make sure the pass phrase is
117 encoded using UTF-8.
118 This is default on most modern Unixes, but may involve an effort on other
119 platforms.
120 Specifically for Windows, setting the environment variable
121 C<OPENSSL_WIN32_UTF8> will have anything entered on [Windows] console prompt
122 converted to UTF-8 (command line and separately prompted pass phrases alike).
123
124 =head2 Opening existing objects
125
126 For opening pass phrase protected objects where you know what character
127 encoding was used for the encryption pass phrase, make sure to use the same
128 encoding again.
129
130 For opening pass phrase protected objects where the character encoding that was
131 used is unknown, or where the producing application is unknown, try one of the
132 following:
133
134 =over 4
135
136 =item 1.
137
138 Try the password that you have as it is in the character encoding of your
139 environment.
140 It's possible that its byte sequence is exactly right.
141
142 =item 2.
143
144 Convert the pass phrase to UTF-8 and try with the result.
145 Specifically with PKCS#12, this should open up any object that was created
146 according to the specification.
147
148 =item 3.
149
150 Do a naïve (i.e. purely mathematical) ISO-8859-1 to UTF-8 conversion and try
151 with the result.
152 This differs from the previous attempt because ISO-8859-1 maps directly to
153 U+0000 to U+00FF, which other non-UTF-8 character sets do not.
154
155 This also takes care of the case when a UTF-8 encoded string was used with
156 OpenSSL older than 1.1.0.
157 (for example, C<ï>, which is 0xC3 0xAF when encoded in UTF-8, would become 0xC3
158 0x83 0xC2 0xAF when re-encoded in the naïve manner.
159 The conversion to BMPString would then yield 0x00 0xC3 0x00 0xA4 0x00 0x00, the
160 erroneous/non-compliant encoding used by OpenSSL older than 1.1.0)
161
162 =back
163
164 =head1 SEE ALSO
165
166 L<evp(7)>,
167 L<ossl_store(7)>,
168 L<EVP_BytesToKey(3)>, L<EVP_DecryptInit(3)>,
169 L<PEM_do_header(3)>,
170 L<PKCS12_parse(3)>, L<PKCS12_newpass(3)>,
171 L<d2i_PKCS8PrivateKey_bio(3)>
172
173 =head1 COPYRIGHT
174
175 Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
176
177 Licensed under the OpenSSL license (the "License").  You may not use
178 this file except in compliance with the License.  You can obtain a copy
179 in the file LICENSE in the source distribution or at
180 L<https://www.openssl.org/source/license.html>.
181
182 =cut