1
package org.bouncycastle.openpgp.test;
3
import org.bouncycastle.bcpg.BCPGOutputStream;
4
import org.bouncycastle.bcpg.HashAlgorithmTags;
5
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
6
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
7
import org.bouncycastle.bcpg.attr.ImageAttribute;
8
import org.bouncycastle.jce.provider.BouncyCastleProvider;
9
import org.bouncycastle.openpgp.PGPCompressedData;
10
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
11
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
12
import org.bouncycastle.openpgp.PGPEncryptedDataList;
13
import org.bouncycastle.openpgp.PGPKeyPair;
14
import org.bouncycastle.openpgp.PGPLiteralData;
15
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
16
import org.bouncycastle.openpgp.PGPObjectFactory;
17
import org.bouncycastle.openpgp.PGPOnePassSignature;
18
import org.bouncycastle.openpgp.PGPOnePassSignatureList;
19
import org.bouncycastle.openpgp.PGPPBEEncryptedData;
20
import org.bouncycastle.openpgp.PGPPrivateKey;
21
import org.bouncycastle.openpgp.PGPPublicKey;
22
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
23
import org.bouncycastle.openpgp.PGPPublicKeyRing;
24
import org.bouncycastle.openpgp.PGPSecretKey;
25
import org.bouncycastle.openpgp.PGPSecretKeyRing;
26
import org.bouncycastle.openpgp.PGPSignature;
27
import org.bouncycastle.openpgp.PGPSignatureGenerator;
28
import org.bouncycastle.openpgp.PGPSignatureList;
29
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector;
30
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVectorGenerator;
31
import org.bouncycastle.openpgp.PGPUtil;
32
import org.bouncycastle.openpgp.PGPV3SignatureGenerator;
33
import org.bouncycastle.util.encoders.Base64;
34
import org.bouncycastle.util.encoders.Hex;
35
import org.bouncycastle.util.test.SimpleTest;
36
import org.bouncycastle.util.test.UncloseableOutputStream;
38
import javax.crypto.Cipher;
39
import java.io.ByteArrayInputStream;
40
import java.io.ByteArrayOutputStream;
41
import java.io.IOException;
42
import java.io.InputStream;
43
import java.io.OutputStream;
44
import java.security.KeyPair;
45
import java.security.KeyPairGenerator;
46
import java.security.PublicKey;
47
import java.security.SecureRandom;
48
import java.security.Security;
49
import java.util.Date;
50
import java.util.Iterator;
52
public class PGPRSATest
55
byte[] testPubKey = Base64.decode(
56
"mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F"
57
+ "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO"
58
+ "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F"
59
+ "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4"
60
+ "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG"
61
+ "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc"
62
+ "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs"
63
+ "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrA==");
65
byte[] testPrivKey = Base64.decode(
66
"lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP"
67
+ "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x"
68
+ "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D"
69
+ "AwKbLeIOVYTEdWD5v/YgW8ERs0pDsSIfBTvsJp2qA798KeFuED6jGsHUzdi1M990"
70
+ "6PRtplQgnoYmYQrzEc6DXAiAtBR4Kuxi4XHx0ZR2wpVlVxm2Ypgz7pbBNWcWqzvw"
71
+ "33inl7tR4IDsRdJOY8cFlN+1tSCf16sDidtKXUVjRjZNYJytH18VfSPlGXMeYgtw"
72
+ "3cSGNTERwKaq5E/SozT2MKTiORO0g0Mtyz+9MEB6XVXFavMun/mXURqbZN/k9BFb"
73
+ "z+TadpkihrLD1xw3Hp+tpe4CwPQ2GdWKI9KNo5gEnbkJgLrSMGgWalPhknlNHRyY"
74
+ "bSq6lbIMJEE3LoOwvYWwweR1+GrV9farJESdunl1mDr5/d6rKru+FFDwZM3na1IF"
75
+ "4Ei4FpqhivZ4zG6pN5XqLy+AK85EiW4XH0yAKX1O4YlbmDU4BjxhiwTdwuVMCjLO"
76
+ "5++jkz5BBQWdFX8CCMA4FJl36G70IbGzuFfOj07ly7QvRXJpYyBFY2hpZG5hICh0"
77
+ "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb"
78
+ "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO"
79
+ "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN"
80
+ "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1"
81
+ "3V73K298L8Lz09habWaq7aJx/znc0/SXX6w=");
83
byte[] testPubKeyV3 = Base64.decode(
84
"mQCNAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO"
85
+ "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB"
86
+ "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F"
87
+ "wdi2fBUJAAURtApGSVhDSVRZX1FBiQCVAwUQP7O+UZ6Fwdi2fBUJAQFMwwQA"
88
+ "qRnFsdg4xQnB8Y5d4cOpXkIn9AZgYS3cxtuSJB84vG2CgC39nfv4c+nlLkWP"
89
+ "4puG+mZuJNgVoE84cuAF4I//1anKjlU7q1M6rFQnt5S4uxPyG3dFXmgyU1b4"
90
+ "PBOnA0tIxjPzlIhJAMsPCGGA5+5M2JP0ad6RnzqzE3EENMX+GqY=");
92
byte[] testPrivKeyV3 = Base64.decode(
93
"lQHfAz+zvlEAAAEEAMS22jgXbOZ/D3xWgM2kauSdzrwlU7Ms5hDW05ObqQyO"
94
+ "FfQoKKMhfupyoa7J3x04VVBKu6Eomvr1es+VImH0esoeWFFahNOYq/I+jRRB"
95
+ "woOhAGZ5UB2/hRd7rFmxqp6sCXi8wmLO2tAorlTzAiNNvl7xF4cQZpc0z56F"
96
+ "wdi2fBUJAAURAXWwRBZQHNikA/f0ScLLjrXi4s0hgQecg+dkpDow94eu5+AR"
97
+ "0DzZnfurpgfUJCNiDi5W/5c3Zj/xyrfMAgkbCgJ1m6FZqAQh7Mq73l7Kfu4/"
98
+ "XIkyDF3tDgRuZNezB+JuElX10tV03xumHepp6M6CfhXqNJ15F33F99TA5hXY"
99
+ "CPYD7SiSOpIhQkCOAgDAA63imxbpuKE2W7Y4I1BUHB7WQi8ZdkZd04njNTv+"
100
+ "rFUuOPapQVfbWG0Vq8ld3YmJB4QWsa2mmqn+qToXbwufAgBpXkjvqK5yPiHF"
101
+ "Px2QbFc1VqoCJB6PO5JRIqEiUZBFGdDlLxt3VSyqz7IZ/zEnxZq+tPCGGGSm"
102
+ "/sAGiMvENcHVAfy0kTXU42TxEAYJyyNyqjXOobDJpEV1mKhFskRXt7tbMfOS"
103
+ "Yf91oX8f6xw6O2Nal+hU8dS0Bmfmk5/enHmvRLHQocO0CkZJWENJVFlfUUE=");
105
byte[] sig1 = Base64.decode(
106
"owGbwMvMwMRoGpHo9vfz52LGNTJJnBmpOTn5eiUVJfb23JvAHIXy/KKcFEWuToap"
107
+ "zKwMIGG4Bqav0SwMy3yParsEKi2LMGI9xhh65sBxb05n5++ZLcWNJ/eLFKdWbm95"
108
+ "tHbDV7GMwj/tUctUpFUXWPYFCLdNsDiVNuXbQvZtdXV/5xzY+9w1nCnijH9JoNiJ"
109
+ "22n2jo0zo30/TZLo+jDl2vTzIvPeLEsPM3ZUE/1Ytqs4SG2TxIQbH7xf3uzcYXq2"
112
byte[] sig1crc = Base64.decode("+3i0");
114
byte[] subKey = Base64.decode(
115
"lQH8BD89pyQBBADk1aljL6mBOvd6k4Myr/0yaSI94SPC5WDwuptXZNM92wy8FVZP"
116
+ "RRQAfglkvEXRTlrfxRt7RL9p83KDXUb47/VgC8iBjWsLWnuDJeqAE9Ov+ddclM1x"
117
+ "zpPvcSt8JFzeY3c1IX+HANqBqS0lf6WZaHLCAy/owlELbplD8BaHZkh4cwAGKf4D"
118
+ "AwKt6ZC7iqsQHGDNn2ZAuhS+ZwiFC+BToW9Vq6rwggWjgM/SThv55rfDk7keiXUT"
119
+ "MyUcZVeYBe4Jttb4fAAm83hNztFu6Jvm9ITcm7YvnasBtVQjppaB+oYZgsTtwK99"
120
+ "LGC3mdexnriCLxPN6tDFkGhzdOcYZfK6py4Ska8Dmq9nOZU9Qtv7Pm3qa5tuBvYw"
121
+ "myTxeaJYifZTu/sky3Gj+REb8WonbgAJX/sLNBPUt+vYko+lxU8uqZpVEMU//hGG"
122
+ "Rns2gIHdbSbIe1vGgIRUEd7Z0b7jfVQLUwqHDyfh5DGvAUhvtJogjUyFIXZzpU+E"
123
+ "9ES9t7LZKdwNZSIdNUjM2eaf4g8BpuQobBVkj/GUcotKyeBjwvKxHlRefL4CCw28"
124
+ "DO3SnLRKxd7uBSqeOGUKxqasgdekM/xIFOrJ85k7p89n6ncLQLHCPGVkzmVeRZro"
125
+ "/T7zE91J57qBGZOUAP1vllcYLty1cs9PCc5oWnj3XbQvRXJpYyBFY2hpZG5hICh0"
126
+ "ZXN0IGtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IuAQTAQIAIgUCPz2nJAIb"
127
+ "AwUJAIPWAAQLBwMCAxUCAwMWAgECHgECF4AACgkQNVhhRv3z83PFjAP/QW47gfBO"
128
+ "PEAJcaIlX/VPEnzXpa8/zjSQP2zL1q/yZzhgPTz5hQ+VHPpFf6voveHRDI7AuQkN"
129
+ "ZqFB1kj9sZUIWzswT9vqD18N89nwbPVyYJ0x+kFjAALy7N7oPaaNJaDRy6G0/w/1"
130
+ "3V73K298L8Lz09habWaq7aJx/znc0/SXX6y0JEVyaWMgRWNoaWRuYSA8ZXJpY0Bi"
131
+ "b3VuY3ljYXN0bGUub3JnPoi4BBMBAgAiBQI/RxQNAhsDBQkAg9YABAsHAwIDFQID"
132
+ "AxYCAQIeAQIXgAAKCRA1WGFG/fPzc3O6A/49tXFCiiP8vg77OXvnmbnzPBA1G6jC"
133
+ "RZNP1yIXusOjpHqyLN5K9hw6lq/o4pNiCuiq32osqGRX3lv/nDduJU1kn2Ow+I2V"
134
+ "ci+ojMXdCGdEqPwZfv47jHLwRrIUJ22OOoWsORtgvSeRUd4Izg8jruaFM7ufr5hr"
135
+ "jEl1cuLW1Hr8Lp0B/AQ/RxxQAQQA0J2BIdqb8JtDGKjvYxrju0urJVVzyI1CnCjA"
136
+ "p7CtLoHQJUQU7PajnV4Jd12ukfcoK7MRraYydQEjxh2MqPpuQgJS3dgQVrxOParD"
137
+ "QYBFrZNd2tZxOjYakhErvUmRo6yWFaxChwqMgl8XWugBNg1Dva+/YcoGQ+ly+Jg4"
138
+ "RWZoH88ABin+AwMCldD/2v8TyT1ghK70IuFs4MZBhdm6VgyGR8DQ/Ago6IAjA4BY"
139
+ "Sol3lJb7+IIGsZaXwEuMRUvn6dWfa3r2I0p1t75vZb1Ng1YK32RZ5DNzl4Xb3L8V"
140
+ "D+1Fiz9mHO8wiplAwDudB+RmQMlth3DNi/UsjeCTdEJAT+TTC7D40DiHDb1bR86Y"
141
+ "2O5Y7MQ3SZs3/x0D/Ob6PStjfQ1kiqbruAMROKoavG0zVgxvspkoKN7h7BapnwJM"
142
+ "6yf4qN/aByhAx9sFvADxu6z3SVcxiFw3IgAmabyWYb85LP8AsTYAG/HBoC6yob47"
143
+ "Mt+GEDeyPifzzGXBWYIH4heZbSQivvA0eRwY5VZsMsBkbY5VR0FLVWgplbuO21bS"
144
+ "rPS1T0crC+Zfj7FQBAkTfsg8RZQ8MPaHng01+gnFd243DDFvTAHygvm6a2X2fiRw"
145
+ "5epAST4wWfY/BZNOxmfSKH6QS0oQMRscw79He6vGTB7vunLrKQYD4veInwQYAQIA"
146
+ "CQUCP0ccUAIbDAAKCRA1WGFG/fPzczmFA/wMg5HhN5NkqmjnHUFfeXNXdHzmekyw"
147
+ "38RnuCMKmfc43AiDs+FtJ62gpQ6PEsZF4o9S5fxcjVk3VSg00XMDtQ/0BsKBc5Gx"
148
+ "hJTq7G+/SoeM433WG19uoS0+5Lf/31wNoTnpv6npOaYpcTQ7L9LCnzwAF4H0hJPE"
149
+ "6bhmW2CMcsE/IZUB4QQ/Rwc1EQQAs5MUQlRiYOfi3fQ1OF6Z3eCwioDKu2DmOxot"
150
+ "BICvdoG2muvs0KEBas9bbd0FJqc92FZJv8yxEgQbQtQAiFxoIFHRTFK+SPO/tQm+"
151
+ "r83nwLRrfDeVVdRfzF79YCc+Abuh8sS/53H3u9Y7DYWr9IuMgI39nrVhY+d8yukf"
152
+ "jo4OR+sAoKS/f7V1Xxj/Eqhb8qzf+N+zJRUlBACDd1eo/zFJZcq2YJa7a9vkViME"
153
+ "axvwApqxeoU7oDpeHEMWg2DXJ7V24ZU5SbPTMY0x98cc8pcoqwsqux8xicWc0reh"
154
+ "U3odQxWM4Se0LmEdca0nQOmNJlL9IsQ+QOJzx47qUOUAqhxnkXxQ/6B8w+M6gZya"
155
+ "fwSdy70OumxESZipeQP+Lo9x6FcaW9L78hDX0aijJhgSEsnGODKB+bln29txX37E"
156
+ "/a/Si+pyeLMi82kUdIL3G3I5HPWd3qSO4K94062+HfFj8bA20/1tbb/WxvxB2sKJ"
157
+ "i3IobblFOvFHo+v8GaLdVyartp0JZLue/jP1dl9ctulSrIqaJT342uLsgTjsr2z+"
158
+ "AwMCAyAU8Vo5AhhgFkDto8vQk7yxyRKEzu5qB66dRcTlaUPIiR8kamcy5ZTtujs4"
159
+ "KIW4j2M/LvagrpWfV5+0M0VyaWMgRWNoaWRuYSAoRFNBIFRlc3QgS2V5KSA8ZXJp"
160
+ "Y0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQI/Rwc1BAsHAwIDFQIDAxYCAQIe"
161
+ "AQIXgAAKCRDNI/XpxMo0QwJcAJ40447eezSiIMspuzkwsMyFN8YBaQCdFTuZuT30"
162
+ "CphiUYWnsC0mQ+J15B4=");
164
byte[] enc1 = Base64.decode(
165
"hIwDKwfQexPJboABA/4/7prhYYMORTiQ5avQKx0XYpCLujzGefYjnyuWZnx3Iev8"
166
+ "Pmsguumm+OLLvtXhhkXQmkJRXbIg6Otj2ubPYWflRPgpJSgOrNOreOl5jeABOrtw"
167
+ "bV6TJb9OTtZuB7cTQSCq2gmYiSZkluIiDjNs3R3mEanILbYzOQ3zKSggKpzlv9JQ"
168
+ "AZUqTyDyJ6/OUbJF5fI5uiv76DCsw1zyMWotUIu5/X01q+AVP5Ly3STzI7xkWg/J"
169
+ "APz4zUHism7kSYz2viAQaJx9/bNnH3AM6qm1Fuyikl4=");
171
byte[] enc1crc = Base64.decode("lv4o");
173
byte[] enc2 = Base64.decode(
174
"hIwDKwfQexPJboABBAC62jcJH8xKnKb1neDVmiovYON04+7VQ2v4BmeHwJrdag1g"
175
+ "Ya++6PeBlQ2Q9lSGBwLobVuJmQ7cOnPUJP727JeSGWlMyFtMbBSHekOaTenT5lj7"
176
+ "Zk7oRHxMp/hByzlMacIDzOn8LPSh515RHM57eDLCOwqnAxGQwk67GRl8f5dFH9JQ"
177
+ "Aa7xx8rjCqPbiIQW6t5LqCNvPZOiSCmftll6+se1XJhFEuq8WS4nXtPfTiJ3vib4"
178
+ "3soJdHzGB6AOs+BQ6aKmmNTVAxa5owhtSt1Z/6dfSSk=");
180
byte[] subPubKey = Base64.decode(
181
"mIsEPz2nJAEEAOTVqWMvqYE693qTgzKv/TJpIj3hI8LlYPC6m1dk0z3bDLwVVk9F"
182
+ "FAB+CWS8RdFOWt/FG3tEv2nzcoNdRvjv9WALyIGNawtae4Ml6oAT06/511yUzXHO"
183
+ "k+9xK3wkXN5jdzUhf4cA2oGpLSV/pZlocsIDL+jCUQtumUPwFodmSHhzAAYptC9F"
184
+ "cmljIEVjaGlkbmEgKHRlc3Qga2V5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPoi4"
185
+ "BBMBAgAiBQI/PackAhsDBQkAg9YABAsHAwIDFQIDAxYCAQIeAQIXgAAKCRA1WGFG"
186
+ "/fPzc8WMA/9BbjuB8E48QAlxoiVf9U8SfNelrz/ONJA/bMvWr/JnOGA9PPmFD5Uc"
187
+ "+kV/q+i94dEMjsC5CQ1moUHWSP2xlQhbOzBP2+oPXw3z2fBs9XJgnTH6QWMAAvLs"
188
+ "3ug9po0loNHLobT/D/XdXvcrb3wvwvPT2FptZqrtonH/OdzT9JdfrIhMBBARAgAM"
189
+ "BQI/RxooBYMAemL8AAoJEM0j9enEyjRDiBgAn3RcLK+gq90PvnQFTw2DNqdq7KA0"
190
+ "AKCS0EEIXCzbV1tfTdCUJ3hVh3btF7QkRXJpYyBFY2hpZG5hIDxlcmljQGJvdW5j"
191
+ "eWNhc3RsZS5vcmc+iLgEEwECACIFAj9HFA0CGwMFCQCD1gAECwcDAgMVAgMDFgIB"
192
+ "Ah4BAheAAAoJEDVYYUb98/Nzc7oD/j21cUKKI/y+Dvs5e+eZufM8EDUbqMJFk0/X"
193
+ "Ihe6w6OkerIs3kr2HDqWr+jik2IK6KrfaiyoZFfeW/+cN24lTWSfY7D4jZVyL6iM"
194
+ "xd0IZ0So/Bl+/juMcvBGshQnbY46haw5G2C9J5FR3gjODyOu5oUzu5+vmGuMSXVy"
195
+ "4tbUevwuiEwEEBECAAwFAj9HGigFgwB6YvwACgkQzSP16cTKNEPwBQCdHm0Amwza"
196
+ "NmVmDHm3rmqI7rp2oQ0An2YbiP/H/kmBNnmTeH55kd253QOhuIsEP0ccUAEEANCd"
197
+ "gSHam/CbQxio72Ma47tLqyVVc8iNQpwowKewrS6B0CVEFOz2o51eCXddrpH3KCuz"
198
+ "Ea2mMnUBI8YdjKj6bkICUt3YEFa8Tj2qw0GARa2TXdrWcTo2GpIRK71JkaOslhWs"
199
+ "QocKjIJfF1roATYNQ72vv2HKBkPpcviYOEVmaB/PAAYpiJ8EGAECAAkFAj9HHFAC"
200
+ "GwwACgkQNVhhRv3z83M5hQP8DIOR4TeTZKpo5x1BX3lzV3R85npMsN/EZ7gjCpn3"
201
+ "ONwIg7PhbSetoKUOjxLGReKPUuX8XI1ZN1UoNNFzA7UP9AbCgXORsYSU6uxvv0qH"
202
+ "jON91htfbqEtPuS3/99cDaE56b+p6TmmKXE0Oy/Swp88ABeB9ISTxOm4ZltgjHLB"
203
+ "PyGZAaIEP0cHNREEALOTFEJUYmDn4t30NThemd3gsIqAyrtg5jsaLQSAr3aBtprr"
204
+ "7NChAWrPW23dBSanPdhWSb/MsRIEG0LUAIhcaCBR0UxSvkjzv7UJvq/N58C0a3w3"
205
+ "lVXUX8xe/WAnPgG7ofLEv+dx97vWOw2Fq/SLjICN/Z61YWPnfMrpH46ODkfrAKCk"
206
+ "v3+1dV8Y/xKoW/Ks3/jfsyUVJQQAg3dXqP8xSWXKtmCWu2vb5FYjBGsb8AKasXqF"
207
+ "O6A6XhxDFoNg1ye1duGVOUmz0zGNMffHHPKXKKsLKrsfMYnFnNK3oVN6HUMVjOEn"
208
+ "tC5hHXGtJ0DpjSZS/SLEPkDic8eO6lDlAKocZ5F8UP+gfMPjOoGcmn8Encu9Drps"
209
+ "REmYqXkD/i6PcehXGlvS+/IQ19GooyYYEhLJxjgygfm5Z9vbcV9+xP2v0ovqcniz"
210
+ "IvNpFHSC9xtyORz1nd6kjuCveNOtvh3xY/GwNtP9bW2/1sb8QdrCiYtyKG25RTrx"
211
+ "R6Pr/Bmi3Vcmq7adCWS7nv4z9XZfXLbpUqyKmiU9+Nri7IE47K9stDNFcmljIEVj"
212
+ "aGlkbmEgKERTQSBUZXN0IEtleSkgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQT"
213
+ "EQIAGQUCP0cHNQQLBwMCAxUCAwMWAgECHgECF4AACgkQzSP16cTKNEMCXACfauui"
214
+ "bSwyG59Yrm8hHCDuCPmqwsQAni+dPl08FVuWh+wb6kOgJV4lcYae");
216
byte[] subPubCrc = Base64.decode("rikt");
218
byte[] pgp8Key = Base64.decode(
219
"lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF"
220
+ "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd"
221
+ "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy"
222
+ "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y"
223
+ "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7"
224
+ "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO"
225
+ "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP"
226
+ "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY"
227
+ "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb"
228
+ "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4"
229
+ "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj"
230
+ "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I"
231
+ "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH"
232
+ "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt"
233
+ "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j"
234
+ "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw"
237
char[] pgp8Pass = "2002 Buffalo Sabres".toCharArray();
239
char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' };
241
byte[] fingerprintKey = Base64.decode(
242
"mQEPA0CiJdUAAAEIAMI+znDlPd2kQoEcnxqxLcRz56Z7ttFKHpnYp0UkljZdquVc"
243
+ "By1jMfXGVV64xN1IvMcyenLXUE0IUeUBCQs6tHunFRAPSeCxJ3FdFe1B5MpqQG8A"
244
+ "BnEpAds/hAUfRDZD5y/lolk1hjvFMrRh6WXckaA/QQ2t00NmTrJ1pYUpkw9tnVQb"
245
+ "LUjWJhfZDBBcN0ADtATzgkugxMtcDxR6I5x8Ndn+IilqIm23kxGIcmMd/BHOec4c"
246
+ "jRwJXXDb7u8tl+2knAf9cwhPHp3+Zy4uGSQPdzQnXOhBlA+4WDa0RROOevWgq8uq"
247
+ "8/9Xp/OlTVL+OoIzjsI6mJP1Joa4qmqAnaHAmXcAEQEAAbQoQk9BM1JTS1kgPEJP"
248
+ "QSBNb25pdG9yaW5nIEAgODg4LTI2OS01MjY2PokBFQMFEECiJdWqaoCdocCZdwEB"
249
+ "0RsH/3HPxoUZ3G3K7T3jgOnJUckTSHWU3XspHzMVgqOxjTrcexi5IsAM5M+BulfW"
250
+ "T2aO+Kqf5w8cKTKgW02DNpHUiPjHx0nzDE+Do95zbIErGeK+Twkc4O/aVsvU9GGO"
251
+ "81VFI6WMvDQ4CUAUnAdk03MRrzI2nAuhn4NJ5LQS+uJrnqUJ4HmFAz6CQZQKd/kS"
252
+ "Xgq+A6i7aI1LG80YxWa9ooQgaCrb9dwY/kPQ+yC22zQ3FExtv+Fv3VtAKTilO3vn"
253
+ "BA4Y9uTHuObHfI+1yxUS2PrlRUX0m48ZjpIX+cEN3QblGBJudI/A1QSd6P0LZeBr"
254
+ "7F1Z1aF7ZDo0KzgiAIBvgXkeTpw=");
256
byte[] fingerprintCheck = Base64.decode("CTv2");
258
byte[] expiry60and30daysSig13Key = Base64.decode(
259
"mQGiBENZt/URBAC5JccXiwe4g6MuviEC8NI/x0NaVkGFAOY04d5E4jeIycBP"
260
+ "SrpOPrjETuigqhrj8oqed2+2yUqfnK4nhTsTAjyeJ3PpWC1pGAKzJgYmJk+K"
261
+ "9aTLq0BQWiXDdv5RG6fDmeq1umvOfcXBqGFAguLPZC+U872bSLnfe3lqGNA8"
262
+ "jvmY7wCgjhzVQVm10NN5ST8nemPEcSjnBrED/R494gHL6+r5OgUgXnNCDejA"
263
+ "4InoDImQCF+g7epp5E1MB6CMYSg2WSY2jHFuHpwnUb7AiOO0ZZ3UBqM9rYnK"
264
+ "kDvxkFCxba7Ms+aFj9blRNmy3vG4FewDcTdxzCtjUk6dRfu6UoARpqlTE/q7"
265
+ "Xo6EQP1ncwJ+UTlcHkTBvg/usI/yBACGjBqX8glb5VfNaZgNHMeS/UIiUiuV"
266
+ "SVFojiSDOHcnCe/6y4M2gVm38zz1W9qhoLfLpiAOFeL0yj6wzXvsjjXQiKQ8"
267
+ "nBE4Mf+oeH2qiQ/LfzQrGpI5eNcMXrzK9nigmz2htYO2GjQfupEnu1RHBTH8"
268
+ "NjofD2AShL9IO73plRuExrQgVGVzdCBLZXkgPHRlc3RAYm91bmN5Y2FzdGxl"
269
+ "Lm9yZz6IZAQTEQIAJAIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAUCQ1m4DgUJ"
270
+ "AE8aGQAKCRD8QP1QuU7Kqw+eAJ0dZ3ZAqr73X61VmCkbyPoszLQMAQCfdFs2"
271
+ "YMDeUvX34Q/8Ba0KgO5f3RSwAgADuM0EQ1m39hADAIHpVGcLqS9UkmQaWBvH"
272
+ "WP6TnN7Y1Ha0TJOuxpbFjBW+CmVh/FjcsnavFXDXpo2zc742WT+vrHBSa/0D"
273
+ "1QEBsnCaX5SRRVp7Mqs8q+aDhjcHMIP8Sdxf7GozXDORkrRaJwADBQL9HLYm"
274
+ "7Rr5iYWDcvs+Pi6O1zUyb1tjkxEGaV/rcozl2MMmr2mzJ6x/Bz8SuhZEJS0m"
275
+ "bB2CvAA39aQi9jHlV7q0SV73NOkd2L/Vt2UZhzlUdvrJ37PgYDv+Wd9Ufz6g"
276
+ "MzLSiE8EGBECAA8FAkNZt/YCGwwFCQAnjQAACgkQ/ED9ULlOyqsTqQCcDnAZ"
277
+ "7YymCfhm1yJiuFQg3qiX6Z4An19OSEgeSKugVcH49g1sxUB0zNdIsAIAAw==");
279
byte[] jpegImage = Base64.decode(
280
"/9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAAAAgAAAAAAAD/2wBDAAUDBAQEAwUE"
281
+ "BAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/"
282
+ "wAALCAA6AFABASIA/8QAHAAAAgMAAwEAAAAAAAAAAAAABQcABAYBAggD/8QAMRAAAgEDBAEDAwME"
283
+ "AQUAAAAAAQIDBAURAAYSITEHIkETFFEjYXEVMkKRCCUzQ4Gh/9oACAEBAAA/APX1TdKCmlaOoqoo"
284
+ "WXzzbiP9nWaS71lXuA2tqrgopBOxpyGyWLAEEd4GAf3+fOjLPXoVaOcNzYAhl8HskADwAPz37f3z"
285
+ "opSvI9Mjypwcr7l/B1XuFwSmoTVooljB9xDYAH51Vor191F9dKGb6Py3yo4huwcHwf8AYP7ZLIyu"
286
+ "gZSGBGQQejrnU1NKn1EqVi3sZJOBCwxxIp9xzksfb5PR+Mdga+ljqIKje1TNBBNToYYgU4477HwQ"
287
+ "Bn9z8/nW6mqxLR0NzpJkMLx8lJUkOGAIx4I/0f41lJ93UkkrRxVKvNKVjZfpSe6RyqhCp7wCSD89"
288
+ "EEDRWppEkgqKdYohGcoZAjAlSMMcZ+PHH/3odsG6VLW2qaoqV+nTyFZpHOFQL0Sc9ADGTnHWtZap"
289
+ "EpoamJm/TgYkfgJ5H/zGuKieVJIGkqCgmfCJFFy64s3Z+Oh58fHyNfGavipIJ2BrZcKXA+mzEd9Y"
290
+ "OCcHI/gDV62SzvBGKhQHaNWzj8jvP750oN/xM3qkshLPEstOhj7IVyvkY+f7Nd7hf9vbc9QbVb7n"
291
+ "dadLldqc00FMCwlmZnCrgL2v/cAySPBPwSD+/wC+3HbWx3rLbaqW81CVHOWnetMZjRm9h7VvClcj"
292
+ "oDB7PymPTvem+a6roxvC10sd3ScmlucdEyUtRADxdice9wY3PQGRgj4OnHU3u5RW+op6imo4q+KA"
293
+ "1UKGQ/bzrnt0biWxkgFOJK9ZyCCVX6f3T1Rh9RawbltdQNv18CGe2wxBDQyvGrowIJd15HEnHvP+"
294
+ "OBjXoGzS0tNTpQipFTIw48Xn5SSBVUMw5e5wMgZ/j86yVNvvZ9TeDR1c9XSV0bl443dmYZXiCSCR"
295
+ "jvxkjR1L1b46iWpStpIRLOWkCqyniP8AJjxPIniBjr+etFdu11DVu321WZiFHRjZcA/gsO+seNYf"
296
+ "fVpq6n1Eo5KNATIYmb5Bx7csP4z/AKz8aX1N6Q7W3FuWWrS1TRzi+tXSutUESQhCGiVAvJVRgfcc"
297
+ "HkeidM6tSmTbps9RHIH4KoqC8j/VC8R0+CSScZLdknPZGgNfYpUUUzfewxxcWpopWbhL715KgBIQ"
298
+ "MCQc4A84+dD963X7ywQ0NIVW60qqzkzIfoszAMGUNyUHORkDrHxo3sSaOhtX2hnp3uNRF9b7hqtO"
299
+ "DxM3Rcj3dMCPHXLGfOkLuPddp9R/ViOa62KppqK3Vctvsz0UylKtWfgXy3+L8WIZFBGRhs407rTT"
300
+ "bcuFDRWmtsNGIZ1MMEU9GPqRorKPcJEzhich8Anz350Wk2zs2OsT7D7RZJpChMEk0MoypJZWVwM9"
301
+ "ZzjWw2lbKaioFjQy/U9shLyu7Esi5JLEnsgnQlaSqhqayWSRZ5JaiSSNPoBCiq54jPuJyA2W+QfA"
302
+ "+FrSXq4bdulZHRpWRzpArPK0SSNUExh14qB4c5X9ipz41Zud0juVouVooHN6rrZKVaoek/VhYgqE"
303
+ "4v7cZPTfPHwT7tZX0e2NVUV5rK2ku9TeY6aFZJ6GuLALKzNnizE4CsqHIyBxJCk4AYFNt2wSUExm"
304
+ "pP1lqgq1zkfXUtIgkiOFHQCsCM/kfOtZU7GsNZU1FFc1lrqCSNSlFOQ8SJk8kC4/tJx1rMwbWt0V"
305
+ "CW21VW+krVoFTCRrPC0bf+NF8ocqMcT/AIg6EVF5/p9U6zPXLVFGpoKlSpMiEkniSCcqVY+eQIPW"
306
+ "NULf/UNxJNS0dhklu8SK9Lco6pUcEr0JOu1HQ7z+R5OndaI5leWV0VQ54kA5KlWIx/Gqd2t6vcqe"
307
+ "FIXNJMs71SoCMsQuG5jsN8AAjyTnrGlt6mVlqswtS0SG71NTXpSiCQFpogckll6Y4wvyD/OToVd7"
308
+ "3tLedda4Nr3iRK2mqJhW1K0qxSSGJf1OTOAwwVADLkA9fPV2W77msVfPTClNRUyJCla0SqS5dR5J"
309
+ "b2kluKlQc5BbHnWu2xTS0G4qmjvSq6RwrPHJUMHkkYDhzJHXIhmBAHnxpaL6j3il3D6g1VLuSz1k"
310
+ "1ht//S6SZQ4KoTI6MyMOb9hR85HedM/0wqn3RsC0bhgq/pQV9J9WELEFaNWGARg+04xkd95xjQTe"
311
+ "df6c7U+ysl3mtMFJe5JYGkkmAVKgKZCZGzlVbBySemA/OgvpZUQxvaqitgoqSsiX6XKh5RwVCBP0"
312
+ "8KCTIoU8VJyDjIA8Bs2e5CprDTR8VXi8pRgyyZMh8qQMDHz850ZOlVv30RsW5blcL5S3a626+1cq"
313
+ "TirFQ0qJIgAQCNjgIMeFKn9wQCMA3o2vprca/ctp29Jv6/3aoZ4IRRx08dC5D8nWQv7FJYHByeuv"
314
+ "zo5SWn1Z2ttahutFZqbcG6JK5ZLu1TNEzzUq5ASNyVw6pxUMc5Oc5znR6KyXffldUVW4rBcbAqos"
315
+ "EUq1qrUzUkwy8bFB+m4ZI2IBbAJAbOdau0+nmybJYqe027atvNHTRlYomhVz+Tln8knyScn50j/+"
316
+ "SOyd3VO2oDtmPcNPYqJgDt23xKtOIiTy6gYO/Z5YOcAHGsJ/x39NgbzuDc+0bNt6/wAySmltbXGv"
317
+ "flaT8ST07xBjIR30RjsL+dex9uwT/wBKo6i5UtPFdHp4/u/pgECTiOQDYBIByB+w0RVEVmZUUM39"
318
+ "xA7P867ampqampqaq09BQwV9RWwUVNFU1AUTTJEoeQLnHJgMnGTjP51a1Nf/2Q==");
320
byte[] embeddedJPEGKey = Base64.decode(
321
"mI0ER0JXuwEEAKNqsXwLU6gu6P2Q/HJqEJVt3A7Kp1yucn8HWVeJF9JLAKVjVU8jrvz9Bw4NwaRJ"
322
+ "NGYEAgdRq8Hx3WP9FXFCIVfCdi+oQrphcHWzzBFul8sykUGT+LmcBdqQGU9WaWSJyCOmUht4j7t0"
323
+ "zk/IXX0YxGmkqR+no5rTj9LMDG8AQQrFABEBAAG0P0VyaWMgSCBFY2hpZG5hIChpbWFnZSB0ZXN0"
324
+ "IGtleSkgPGVyaWMuZWNoaWRuYUBib3VuY3ljYXN0bGUub3JnPoi2BBMBAgAgBQJHQle7AhsDBgsJ"
325
+ "CAcDAgQVAggDBBYCAwECHgECF4AACgkQ1+RWqFFpjMTKtgP+Okqkn0gVpQyNYXM/hWX6f3UQcyXk"
326
+ "2Sd/fWW0XG+LBjhhBo+lXRWK0uYF8OMdZwsSl9HimpgYD5/kNs0Seh417DioP1diOgxkgezyQgMa"
327
+ "+ODZfNnIvVaBr1pHLPLeqIBxBVMWBfa4wDXnLLGu8018uvI2yBhz5vByB1ntxwgKMXCwAgAD0cf3"
328
+ "x/UBEAABAQAAAAAAAAAAAAAAAP/Y/+AAEEpGSUYAAQEBAEgASAAA/+EAFkV4aWYAAE1NACoAAAAI"
329
+ "AAAAAAAA/9sAQwAFAwQEBAMFBAQEBQUFBgcMCAcHBwcPCwsJDBEPEhIRDxERExYcFxMUGhURERgh"
330
+ "GBodHR8fHxMXIiQiHiQcHh8e/8AACwgAOgBQAQEiAP/EABwAAAIDAAMBAAAAAAAAAAAAAAUHAAQG"
331
+ "AQIIA//EADEQAAIBAwQBAwMDBAEFAAAAAAECAwQFEQAGEiExByJBExRRI2FxFTJCkQglM0OBof/a"
332
+ "AAgBAQAAPwD19U3SgppWjqKqKFl8824j/Z1mku9ZV7gNraq4KKQTsachsliwBBHeBgH9/nzoyz16"
333
+ "FWjnDc2AIZfB7JAA8AD89+3986KUryPTI8qcHK+5fwdV7hcEpqE1aKJYwfcQ2AB+dVaK9fdRfXSh"
334
+ "m+j8t8qOIbsHB8H/AGD+2SyMroGUhgRkEHo651NTSp9RKlYt7GSTgQsMcSKfcc5LH2+T0fjHYGvp"
335
+ "Y6iCo3tUzQQTU6GGIFOOO+x8EAZ/c/P51upqsS0dDc6SZDC8fJSVJDhgCMeCP9H+NZSfd1JJK0cV"
336
+ "SrzSlY2X6UnukcqoQqe8Akg/PRBA0VqaRJIKinWKIRnKGQIwJUjDHGfjxx/96HbBulS1tqmqKlfp"
337
+ "08hWaRzhUC9EnPQAxk5x1rWWqRKaGpiZv04GJH4CeR/8xrionlSSBpKgoJnwiRRcuuLN2fjoefHx"
338
+ "8jXxmr4qSCdga2XClwPpsxHfWDgnByP4A1etks7wRioUB2jVs4/I7z++dKDf8TN6pLISzxLLToY+"
339
+ "yFcr5GPn+zXe4X/b23PUG1W+53WnS5XanNNBTAsJZmZwq4C9r/3AMkjwT8Eg/v8Avtx21sd6y22q"
340
+ "lvNQlRzlp3rTGY0ZvYe1bwpXI6Awez8pj073pvmuq6MbwtdLHd0nJpbnHRMlLUQA8XYnHvcGNz0B"
341
+ "kYI+Dpx1N7uUVvqKeopqOKvigNVChkP28657dG4lsZIBTiSvWcgglV+n909UYfUWsG5bXUDb9fAh"
342
+ "ntsMQQ0Mrxq6MCCXdeRxJx7z/jgY16Bs0tLTU6UIqRUyMOPF5+UkgVVDMOXucDIGf4/OslTb72fU"
343
+ "3g0dXPV0ldG5eON3ZmGV4gkgkY78ZI0dS9W+OolqUraSESzlpAqsp4j/ACY8TyJ4gY6/nrRXbtdQ"
344
+ "1bt9tVmYhR0Y2XAP4LDvrHjWH31aaup9RKOSjQEyGJm+Qce3LD+M/wCs/Gl9TekO1txbllq0tU0c"
345
+ "4vrV0rrVBEkIQholQLyVUYH3HB5HonTOrUpk26bPURyB+CqKgvI/1QvEdPgkknGS3ZJz2RoDX2KV"
346
+ "FFM33sMcXFqaKVm4S+9eSoASEDAkHOAPOPnQ/et1+8sENDSFVutKqs5MyH6LMwDBlDclBzkZA6x8"
347
+ "aN7EmjobV9oZ6d7jURfW+4arTg8TN0XI93TAjx1yxnzpC7j3XafUf1Yjmutiqaait1XLb7M9FMpS"
348
+ "rVn4F8t/i/FiGRQRkYbONO60023LhQ0VprbDRiGdTDBFPRj6kaKyj3CRM4YnIfAJ89+dFpNs7Njr"
349
+ "E+w+0WSaQoTBJNDKMqSWVlcDPWc41sNpWymoqBY0Mv1PbIS8ruxLIuSSxJ7IJ0JWkqoamslkkWeS"
350
+ "WokkjT6AQoqueIz7icgNlvkHwPha0l6uG3bpWR0aVkc6QKzytEkjVBMYdeKgeHOV/Yqc+NWbndI7"
351
+ "laLlaKBzeq62SlWqHpP1YWIKhOL+3GT03zx8E+7WV9HtjVVFeaytpLvU3mOmhWSehriwCyszZ4sx"
352
+ "OArKhyMgcSQpOAGBTbdsElBMZqT9ZaoKtc5H11LSIJIjhR0ArAjP5HzrWVOxrDWVNRRXNZa6gkjU"
353
+ "pRTkPEiZPJAuP7ScdazMG1rdFQlttVVvpK1aBUwkazwtG3/jRfKHKjHE/wCIOhFRef6fVOsz1y1R"
354
+ "RqaCpUqTIhJJ4kgnKlWPnkCD1jVC3/1DcSTUtHYZJbvEivS3KOqVHBK9CTrtR0O8/keTp3WiOZXl"
355
+ "ldFUOeJAOSpViMfxqndrer3KnhSFzSTLO9UqAjLELhuY7DfAAI8k56xpbeplZarMLUtEhu9TU16U"
356
+ "ogkBaaIHJJZemOML8g/zk6FXe97S3nXWuDa94kStpqiYVtStKsUkhiX9TkzgMMFQAy5APXz1dlu+"
357
+ "5rFXz0wpTUVMiQpWtEqkuXUeSW9pJbipUHOQWx51rtsU0tBuKpo70qukcKzxyVDB5JGA4cyR1yIZ"
358
+ "gQB58aWi+o94pdw+oNVS7ks9ZNYbf/0ukmUOCqEyOjMjDm/YUfOR3nTP9MKp90bAtG4YKv6UFfSf"
359
+ "VhCxBWjVhgEYPtOMZHfecY0E3nX+nO1PsrJd5rTBSXuSWBpJJgFSoCmQmRs5VWwcknpgPzoL6WVE"
360
+ "Mb2qorYKKkrIl+lyoeUcFQgT9PCgkyKFPFScg4yAPAbNnuQqaw00fFV4vKUYMsmTIfKkDAx8/OdG"
361
+ "TpVb99EbFuW5XC+Ut2utuvtXKk4qxUNKiSIAEAjY4CDHhSp/cEAjAN6Nr6a3Gv3LadvSb+v92qGe"
362
+ "CEUcdPHQuQ/J1kL+xSWBwcnrr86OUlp9WdrbWobrRWam3BuiSuWS7tUzRM81KuQEjclcOqcVDHOT"
363
+ "nOc50eisl335XVFVuKwXGwKqLBFKtaq1M1JMMvGxQfpuGSNiAWwCQGznWrtPp5smyWKntNu2rbzR"
364
+ "00ZWKJoVc/k5Z/JJ8knJ+dI//kjsnd1TtqA7Zj3DT2KiYA7dt8SrTiIk8uoGDv2eWDnABxrCf8d/"
365
+ "TYG87g3PtGzbev8AMkppbW1xr35Wk/Ek9O8QYyEd9EY7C/nXsfbsE/8ASqOouVLTxXR6eP7v6YBA"
366
+ "k4jkA2ASAcgfsNEVRFZmVFDN/cQOz/Ou2pqampqamqtPQUMFfUVsFFTRVNQFE0yRKHkC5xyYDJxk"
367
+ "4z+dWtTX/9mItgQTAQIAIAUCR0JYkAIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJENfkVqhR"
368
+ "aYzEAPYD/iHdLOAE8r8HHF3F4z28vtIT8iiRB9aPC/YH0xqV1qeEKG8+VosBaQAOCEquONtRWsww"
369
+ "gO3XB0d6VAq2kMOKc2YiB4ZtZcFvvmP9KdmVIZxVjpa9ozjP5j9zFso1HOpFcsn/VDBEqy5TvsNx"
370
+ "Qvmtc8X7lqK/zLRVkSSBItik2IIhsAIAAw==");
373
private void fingerPrintTest()
379
PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(fingerprintKey);
381
PGPPublicKey pubKey = pgpPub.getPublicKey();
383
if (!areEqual(pubKey.getFingerprint(), Hex.decode("4FFB9F0884266C715D1CEAC804A3BBFA")))
385
fail("version 3 fingerprint test failed");
391
pgpPub = new PGPPublicKeyRing(testPubKey);
393
pubKey = pgpPub.getPublicKey();
395
if (!areEqual(pubKey.getFingerprint(), Hex.decode("3062363c1046a01a751946bb35586146fdf3f373")))
397
fail("version 4 fingerprint test failed");
401
private void mixedTest(PGPPrivateKey pgpPrivKey, PGPPublicKey pgpPubKey)
404
byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' };
409
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
410
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
411
OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, text.length, new Date());
417
byte[] bytes = bOut.toByteArray();
419
PGPObjectFactory f = new PGPObjectFactory(bytes);
420
checkLiteralData((PGPLiteralData)f.nextObject(), text);
422
ByteArrayOutputStream bcOut = new ByteArrayOutputStream();
424
PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(SymmetricKeyAlgorithmTags.AES_128, true, new SecureRandom(), "BC");
426
encGen.addMethod(pgpPubKey);
428
encGen.addMethod("password".toCharArray());
430
OutputStream cOut = encGen.open(bcOut, bytes.length);
436
byte[] encData = bcOut.toByteArray();
441
PGPObjectFactory pgpF = new PGPObjectFactory(encData);
443
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
445
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
447
InputStream clear = encP.getDataStream(pgpPrivKey, "BC");
449
PGPObjectFactory pgpFact = new PGPObjectFactory(clear);
451
checkLiteralData((PGPLiteralData)pgpFact.nextObject(), text);
456
pgpF = new PGPObjectFactory(encData);
458
encList = (PGPEncryptedDataList)pgpF.nextObject();
460
PGPPBEEncryptedData encPbe = (PGPPBEEncryptedData)encList.get(1);
462
clear = encPbe.getDataStream("password".toCharArray(), "BC");
464
pgpF = new PGPObjectFactory(clear);
466
checkLiteralData((PGPLiteralData)pgpF.nextObject(), text);
469
private void checkLiteralData(PGPLiteralData ld, byte[] data)
472
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
474
if (!ld.getFileName().equals(PGPLiteralData.CONSOLE))
476
throw new RuntimeException("wrong filename in packet");
479
InputStream inLd = ld.getDataStream();
482
while ((ch = inLd.read()) >= 0)
487
if (!areEqual(bOut.toByteArray(), data))
489
fail("wrong plain text in decrypted packet");
493
private void existingEmbeddedJpegTest()
496
PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(embeddedJPEGKey);
498
PGPPublicKey pubKey = pgpPub.getPublicKey();
500
Iterator it = pubKey.getUserAttributes();
504
PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next();
506
Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes);
508
while (sigs.hasNext())
510
PGPSignature sig = (PGPSignature)sigs.next();
512
sig.initVerify(pubKey, "BC");
514
if (!sig.verifyCertification(attributes, pubKey))
516
fail("signature failed verification");
524
fail("Failed user attributes signature check");
531
fail("didn't find user attributes");
535
private void embeddedJpegTest()
538
PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey);
539
PGPSecretKeyRing pgpSec = new PGPSecretKeyRing(testPrivKey);
541
PGPPublicKey pubKey = pgpPub.getPublicKey();
543
PGPUserAttributeSubpacketVectorGenerator vGen = new PGPUserAttributeSubpacketVectorGenerator();
545
vGen.setImageAttribute(ImageAttribute.JPEG, jpegImage);
547
PGPUserAttributeSubpacketVector uVec = vGen.generate();
549
PGPSignatureGenerator sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, "BC");
551
sGen.initSign(PGPSignature.POSITIVE_CERTIFICATION, pgpSec.getSecretKey().extractPrivateKey(pass, "BC"));
553
PGPSignature sig = sGen.generateCertification(uVec, pubKey);
555
PGPPublicKey nKey = PGPPublicKey.addCertification(pubKey, uVec, sig);
557
Iterator it = nKey.getUserAttributes();
561
PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next();
563
Iterator sigs = nKey.getSignaturesForUserAttribute(attributes);
565
while (sigs.hasNext())
567
PGPSignature s = (PGPSignature)sigs.next();
569
s.initVerify(pubKey, "BC");
571
if (!s.verifyCertification(attributes, pubKey))
573
fail("added signature failed verification");
581
fail("Failed added user attributes signature check");
588
fail("didn't find added user attributes");
591
nKey = PGPPublicKey.removeCertification(nKey, uVec);
593
for (it = nKey.getUserAttributes(); it.hasNext();)
599
fail("found attributes where none expected");
603
public void performTest()
606
PublicKey pubKey = null;
609
// Read the public key
611
PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey);
613
pubKey = pgpPub.getPublicKey().getKey("BC");
615
Iterator it = pgpPub.getPublicKey().getUserIDs();
617
String uid = (String)it.next();
619
it = pgpPub.getPublicKey().getSignaturesForID(uid);
621
PGPSignature sig = (PGPSignature)it.next();
623
sig.initVerify(pgpPub.getPublicKey(), "BC");
625
if (!sig.verifyCertification(uid, pgpPub.getPublicKey()))
627
fail("failed to verify certification");
631
// write a public key
633
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
634
BCPGOutputStream pOut = new BCPGOutputStream(bOut);
638
if (!areEqual(bOut.toByteArray(), testPubKey))
640
fail("public key rewrite failed");
644
// Read the public key
646
PGPPublicKeyRing pgpPubV3 = new PGPPublicKeyRing(testPubKeyV3);
647
PublicKey pubKeyV3 = pgpPub.getPublicKey().getKey("BC");
650
// write a V3 public key
652
bOut = new ByteArrayOutputStream();
653
pOut = new BCPGOutputStream(bOut);
655
pgpPubV3.encode(pOut);
658
// Read a v3 private key
660
char[] passP = "FIXCITY_QA".toCharArray();
664
PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKeyV3);
665
PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(passP, "BC");
668
// write a v3 private key
670
bOut = new ByteArrayOutputStream();
671
pOut = new BCPGOutputStream(bOut);
673
pgpPriv.encode(pOut);
675
if (!areEqual(bOut.toByteArray(), testPrivKeyV3))
677
fail("private key V3 rewrite failed");
682
// Read the private key
684
PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKey);
685
PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(pass, "BC");
688
// write a private key
690
bOut = new ByteArrayOutputStream();
691
pOut = new BCPGOutputStream(bOut);
693
pgpPriv.encode(pOut);
695
if (!areEqual(bOut.toByteArray(), testPrivKey))
697
fail("private key rewrite failed");
704
Cipher c = Cipher.getInstance("RSA", "BC");
706
c.init(Cipher.ENCRYPT_MODE, pubKey);
708
byte[] in = "hello world".getBytes();
710
byte[] out = c.doFinal(in);
712
c.init(Cipher.DECRYPT_MODE, pgpPrivKey.getKey());
714
out = c.doFinal(out);
716
if (!areEqual(in, out))
718
fail("decryption failed.");
722
// test signature message
724
PGPObjectFactory pgpFact = new PGPObjectFactory(sig1);
726
PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject();
728
pgpFact = new PGPObjectFactory(c1.getDataStream());
730
PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
732
PGPOnePassSignature ops = p1.get(0);
734
PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject();
736
InputStream dIn = p2.getInputStream();
739
ops.initVerify(pgpPub.getPublicKey(ops.getKeyID()), "BC");
741
while ((ch = dIn.read()) >= 0)
743
ops.update((byte)ch);
746
PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject();
748
if (!ops.verify(p3.get(0)))
750
fail("Failed signature check");
754
// encrypted message - read subkey
756
pgpPriv = new PGPSecretKeyRing(subKey);
761
byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' };
763
PGPObjectFactory pgpF = new PGPObjectFactory(enc1);
765
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
767
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
769
pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(pass, "BC");
771
InputStream clear = encP.getDataStream(pgpPrivKey, "BC");
773
pgpFact = new PGPObjectFactory(clear);
775
c1 = (PGPCompressedData)pgpFact.nextObject();
777
pgpFact = new PGPObjectFactory(c1.getDataStream());
779
PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject();
781
bOut = new ByteArrayOutputStream();
783
if (!ld.getFileName().equals("test.txt"))
785
throw new RuntimeException("wrong filename in packet");
788
InputStream inLd = ld.getDataStream();
790
while ((ch = inLd.read()) >= 0)
795
if (!areEqual(bOut.toByteArray(), text))
797
fail("wrong plain text in decrypted packet");
801
// encrypt - short message
803
byte[] shortText = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' };
805
ByteArrayOutputStream cbOut = new ByteArrayOutputStream();
806
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(SymmetricKeyAlgorithmTags.CAST5, new SecureRandom(), "BC");
807
PGPPublicKey puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey();
811
OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), shortText.length);
813
cOut.write(shortText);
817
pgpF = new PGPObjectFactory(cbOut.toByteArray());
819
encList = (PGPEncryptedDataList)pgpF.nextObject();
821
encP = (PGPPublicKeyEncryptedData)encList.get(0);
823
pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(pass, "BC");
825
if (encP.getSymmetricAlgorithm(pgpPrivKey, "BC") != SymmetricKeyAlgorithmTags.CAST5)
827
fail("symmetric algorithm mismatch");
830
clear = encP.getDataStream(pgpPrivKey, "BC");
834
while ((ch = clear.read()) >= 0)
839
out = bOut.toByteArray();
841
if (!areEqual(out, shortText))
843
fail("wrong plain text in generated short text packet");
849
cbOut = new ByteArrayOutputStream();
850
cPk = new PGPEncryptedDataGenerator(SymmetricKeyAlgorithmTags.CAST5, new SecureRandom(), "BC");
851
puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey();
855
cOut = cPk.open(new UncloseableOutputStream(cbOut), text.length);
861
pgpF = new PGPObjectFactory(cbOut.toByteArray());
863
encList = (PGPEncryptedDataList)pgpF.nextObject();
865
encP = (PGPPublicKeyEncryptedData)encList.get(0);
867
pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(pass, "BC");
869
clear = encP.getDataStream(pgpPrivKey, "BC");
873
while ((ch = clear.read()) >= 0)
878
out = bOut.toByteArray();
880
if (!areEqual(out, text))
882
fail("wrong plain text in generated packet");
886
// read public key with sub key.
888
pgpF = new PGPObjectFactory(subPubKey);
891
while ((o = pgpFact.nextObject()) != null)
893
// System.out.println(o);
897
// key pair generation - CAST5 encryption
899
char[] passPhrase = "hello".toCharArray();
901
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
903
kpg.initialize(1024);
905
KeyPair kp = kpg.generateKeyPair();
907
PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, PublicKeyAlgorithmTags.RSA_GENERAL, kp.getPublic(), kp.getPrivate(), new Date(), "fred", SymmetricKeyAlgorithmTags.CAST5, passPhrase, null, null, new SecureRandom(), "BC");
909
PGPPublicKey key = secretKey.getPublicKey();
911
it = key.getUserIDs();
913
uid = (String)it.next();
915
it = key.getSignaturesForID(uid);
917
sig = (PGPSignature)it.next();
919
sig.initVerify(key, "BC");
921
if (!sig.verifyCertification(uid, key))
923
fail("failed to verify certification");
926
pgpPrivKey = secretKey.extractPrivateKey(passPhrase, "BC");
928
key = PGPPublicKey.removeCertification(key, uid, sig);
932
fail("failed certification removal");
935
byte[] keyEnc = key.getEncoded();
937
key = PGPPublicKey.addCertification(key, uid, sig);
939
keyEnc = key.getEncoded();
941
PGPSignatureGenerator sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, "BC");
943
sGen.initSign(PGPSignature.KEY_REVOCATION, secretKey.extractPrivateKey(passPhrase, "BC"));
945
sig = sGen.generateCertification(key);
947
key = PGPPublicKey.addCertification(key, sig);
949
keyEnc = key.getEncoded();
951
PGPPublicKeyRing tmpRing = new PGPPublicKeyRing(keyEnc);
953
key = tmpRing.getPublicKey();
955
Iterator sgIt = key.getSignaturesOfType(PGPSignature.KEY_REVOCATION);
957
sig = (PGPSignature)sgIt.next();
959
sig.initVerify(key, "BC");
961
if (!sig.verifyCertification(key))
963
fail("failed to verify revocation certification");
969
PGPKeyPair pgpKp = new PGPKeyPair(PGPPublicKey.RSA_GENERAL , kp.getPublic(), kp.getPrivate(), new Date());
971
PGPPublicKey k1 = pgpKp.getPublicKey();
973
PGPPrivateKey k2 = pgpKp.getPrivateKey();
980
// key pair generation - AES_256 encryption.
982
kp = kpg.generateKeyPair();
984
secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, PublicKeyAlgorithmTags.RSA_GENERAL, kp.getPublic(), kp.getPrivate(), new Date(), "fred", SymmetricKeyAlgorithmTags.AES_256, passPhrase, null, null, new SecureRandom(), "BC");
986
secretKey.extractPrivateKey(passPhrase, "BC");
988
secretKey.encode(new ByteArrayOutputStream());
991
// secret key password changing.
993
String newPass = "newPass";
995
secretKey = PGPSecretKey.copyWithNewPassword(secretKey, passPhrase, newPass.toCharArray(), secretKey.getKeyEncryptionAlgorithm(), new SecureRandom(), "BC");
997
secretKey.extractPrivateKey(newPass.toCharArray(), "BC");
999
secretKey.encode(new ByteArrayOutputStream());
1001
key = secretKey.getPublicKey();
1003
key.encode(new ByteArrayOutputStream());
1005
it = key.getUserIDs();
1007
uid = (String)it.next();
1009
it = key.getSignaturesForID(uid);
1011
sig = (PGPSignature)it.next();
1013
sig.initVerify(key, "BC");
1015
if (!sig.verifyCertification(uid, key))
1017
fail("failed to verify certification");
1020
pgpPrivKey = secretKey.extractPrivateKey(newPass.toCharArray(), "BC");
1023
// signature generation
1025
String data = "hello world!";
1027
bOut = new ByteArrayOutputStream();
1029
ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes());
1031
sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, "BC");
1033
sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
1035
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
1036
PGPCompressedData.ZIP);
1038
BCPGOutputStream bcOut = new BCPGOutputStream(
1039
cGen.open(new UncloseableOutputStream(bOut)));
1041
sGen.generateOnePassVersion(false).encode(bcOut);
1043
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
1045
Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000);
1046
OutputStream lOut = lGen.open(
1047
new UncloseableOutputStream(bcOut),
1048
PGPLiteralData.BINARY,
1050
data.getBytes().length,
1053
while ((ch = testIn.read()) >= 0)
1056
sGen.update((byte)ch);
1061
sGen.generate().encode(bcOut);
1066
// verify generated signature
1068
pgpFact = new PGPObjectFactory(bOut.toByteArray());
1070
c1 = (PGPCompressedData)pgpFact.nextObject();
1072
pgpFact = new PGPObjectFactory(c1.getDataStream());
1074
p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
1078
p2 = (PGPLiteralData)pgpFact.nextObject();
1079
if (!p2.getModificationTime().equals(testDate))
1081
fail("Modification time not preserved: " + p2.getModificationTime() + " " + testDate);
1084
dIn = p2.getInputStream();
1086
ops.initVerify(secretKey.getPublicKey(), "BC");
1088
while ((ch = dIn.read()) >= 0)
1090
ops.update((byte)ch);
1093
p3 = (PGPSignatureList)pgpFact.nextObject();
1095
if (!ops.verify(p3.get(0)))
1097
fail("Failed generated signature check");
1101
// signature generation - version 3
1103
bOut = new ByteArrayOutputStream();
1105
testIn = new ByteArrayInputStream(data.getBytes());
1106
PGPV3SignatureGenerator sGenV3 = new PGPV3SignatureGenerator(PGPPublicKey.RSA_GENERAL, PGPUtil.SHA1, "BC");
1108
sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
1110
cGen = new PGPCompressedDataGenerator(
1111
PGPCompressedData.ZIP);
1113
bcOut = new BCPGOutputStream(cGen.open(bOut));
1115
sGen.generateOnePassVersion(false).encode(bcOut);
1117
lGen = new PGPLiteralDataGenerator();
1119
new UncloseableOutputStream(bcOut),
1120
PGPLiteralData.BINARY,
1122
data.getBytes().length,
1125
while ((ch = testIn.read()) >= 0)
1128
sGen.update((byte)ch);
1133
sGen.generate().encode(bcOut);
1138
// verify generated signature
1140
pgpFact = new PGPObjectFactory(bOut.toByteArray());
1142
c1 = (PGPCompressedData)pgpFact.nextObject();
1144
pgpFact = new PGPObjectFactory(c1.getDataStream());
1146
p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
1150
p2 = (PGPLiteralData)pgpFact.nextObject();
1151
if (!p2.getModificationTime().equals(testDate))
1153
fail("Modification time not preserved");
1156
dIn = p2.getInputStream();
1158
ops.initVerify(secretKey.getPublicKey(), "BC");
1160
while ((ch = dIn.read()) >= 0)
1162
ops.update((byte)ch);
1165
p3 = (PGPSignatureList)pgpFact.nextObject();
1167
if (!ops.verify(p3.get(0)))
1169
fail("Failed v3 generated signature check");
1173
// extract PGP 8 private key
1175
pgpPriv = new PGPSecretKeyRing(pgp8Key);
1177
secretKey = pgpPriv.getSecretKey();
1179
pgpPrivKey = secretKey.extractPrivateKey(pgp8Pass, "BC");
1184
testExpiry(expiry60and30daysSig13Key, 60, 30);
1187
existingEmbeddedJpegTest();
1191
private void testExpiry(
1197
PGPPublicKeyRing pubRing = new PGPPublicKeyRing(encodedRing);
1198
PGPPublicKey k = pubRing.getPublicKey();
1200
if (k.getValidDays() != masterDays)
1202
fail("mismatch on master valid days.");
1205
Iterator it = pubRing.getPublicKeys();
1209
k = (PGPPublicKey)it.next();
1211
if (k.getValidDays() != subKeyDays)
1213
fail("mismatch on subkey valid days.");
1217
private boolean noIDEA()
1221
Cipher.getInstance("IDEA", "BC");
1231
public String getName()
1233
return "PGPRSATest";
1236
public static void main(
1239
Security.addProvider(new BouncyCastleProvider());
1241
runTest(new PGPRSATest());