2 # PyGOST -- Pure Python GOST cryptographic functions library
3 # Copyright (C) 2015-2020 Sergey Matveev <stargrave@stargrave.org>
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, version 3 of the License.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 from base64 import b64decode
18 from unittest import skipIf
19 from unittest import TestCase
21 from pygost.gost3410 import CURVES
22 from pygost.gost3410 import prv_unmarshal
23 from pygost.gost3410 import pub_marshal
24 from pygost.gost3410 import pub_unmarshal
25 from pygost.gost3410 import public_key
26 from pygost.gost3410 import verify
27 from pygost.gost34112012256 import GOST34112012256
28 from pygost.gost34112012512 import GOST34112012512
29 from pygost.utils import hexdec
33 from pyderasn import Any
34 from pyderasn import BitString
35 from pyderasn import Boolean
36 from pyderasn import GeneralizedTime
37 from pyderasn import Integer
38 from pyderasn import OctetString
39 from pyderasn import PrintableString
40 from pyderasn import UTCTime
42 from pygost.asn1schemas.oids import id_at_commonName
43 from pygost.asn1schemas.oids import id_ce_basicConstraints
44 from pygost.asn1schemas.oids import id_GostR3410_2001_TestParamSet
45 from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256
46 from pygost.asn1schemas.oids import id_tc26_gost3410_2012_256_paramSetA
47 from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512
48 from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetTest
49 from pygost.asn1schemas.oids import id_tc26_gost3411_2012_256
50 from pygost.asn1schemas.oids import id_tc26_signwithdigest_gost3410_2012_256
51 from pygost.asn1schemas.oids import id_tc26_signwithdigest_gost3410_2012_512
52 from pygost.asn1schemas.pkcs10 import Attributes
53 from pygost.asn1schemas.pkcs10 import CertificationRequest
54 from pygost.asn1schemas.pkcs10 import CertificationRequestInfo
55 from pygost.asn1schemas.x509 import AlgorithmIdentifier
56 from pygost.asn1schemas.x509 import AttributeType
57 from pygost.asn1schemas.x509 import AttributeTypeAndValue
58 from pygost.asn1schemas.x509 import AttributeValue
59 from pygost.asn1schemas.x509 import BasicConstraints
60 from pygost.asn1schemas.x509 import Certificate
61 from pygost.asn1schemas.x509 import CertificateList
62 from pygost.asn1schemas.x509 import CertificateSerialNumber
63 from pygost.asn1schemas.x509 import Extension
64 from pygost.asn1schemas.x509 import Extensions
65 from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters
66 from pygost.asn1schemas.x509 import Name
67 from pygost.asn1schemas.x509 import RDNSequence
68 from pygost.asn1schemas.x509 import RelativeDistinguishedName
69 from pygost.asn1schemas.x509 import SubjectPublicKeyInfo
70 from pygost.asn1schemas.x509 import TBSCertificate
71 from pygost.asn1schemas.x509 import TBSCertList
72 from pygost.asn1schemas.x509 import Time
73 from pygost.asn1schemas.x509 import Validity
74 from pygost.asn1schemas.x509 import Version
77 pyderasn_exists = False
79 pyderasn_exists = True
82 @skipIf(not pyderasn_exists, "PyDERASN dependency is required")
83 class TestCertificate(TestCase):
84 """Certificate test vectors from "Использования алгоритмов ГОСТ Р
85 34.10, ГОСТ Р 34.11 в профиле сертификата и списке отзыва
86 сертификатов (CRL) инфраструктуры открытых ключей X.509"
90 def process_cert(self, curve_name, mode, hasher, prv_key_raw, cert_raw):
91 cert, tail = Certificate().decode(cert_raw, ctx={
96 "subjectPublicKeyInfo",
102 ("..", "subjectPublicKey"),
104 id_tc26_gost3410_2012_256: OctetString(),
105 id_tc26_gost3410_2012_512: OctetString(),
112 self.assertSequenceEqual(tail, b"")
113 curve = CURVES[curve_name]
114 prv_key = prv_unmarshal(prv_key_raw)
115 spk = cert["tbsCertificate"]["subjectPublicKeyInfo"]["subjectPublicKey"]
116 self.assertIsNotNone(spk.defined)
117 _, pub_key_raw = spk.defined
118 pub_key = pub_unmarshal(bytes(pub_key_raw), mode=mode)
119 self.assertSequenceEqual(pub_key, public_key(curve, prv_key))
120 self.assertTrue(verify(
123 hasher(cert["tbsCertificate"].encode()).digest()[::-1],
124 bytes(cert["signatureValue"]),
129 cert_raw = b64decode("""
130 MIICYjCCAg+gAwIBAgIBATAKBggqhQMHAQEDAjBWMSkwJwYJKoZIhvcNAQkBFhpH
131 b3N0UjM0MTAtMjAxMkBleGFtcGxlLmNvbTEpMCcGA1UEAxMgR29zdFIzNDEwLTIw
132 MTIgKDI1NiBiaXQpIGV4YW1wbGUwHhcNMTMxMTA1MTQwMjM3WhcNMzAxMTAxMTQw
133 MjM3WjBWMSkwJwYJKoZIhvcNAQkBFhpHb3N0UjM0MTAtMjAxMkBleGFtcGxlLmNv
134 bTEpMCcGA1UEAxMgR29zdFIzNDEwLTIwMTIgKDI1NiBiaXQpIGV4YW1wbGUwZjAf
135 BggqhQMHAQEBATATBgcqhQMCAiQABggqhQMHAQECAgNDAARAut/Qw1MUq9KPqkdH
136 C2xAF3K7TugHfo9n525D2s5mFZdD5pwf90/i4vF0mFmr9nfRwMYP4o0Pg1mOn5Rl
137 aXNYraOBwDCBvTAdBgNVHQ4EFgQU1fIeN1HaPbw+XWUzbkJ+kHJUT0AwCwYDVR0P
138 BAQDAgHGMA8GA1UdEwQIMAYBAf8CAQEwfgYDVR0BBHcwdYAU1fIeN1HaPbw+XWUz
139 bkJ+kHJUT0ChWqRYMFYxKTAnBgkqhkiG9w0BCQEWGkdvc3RSMzQxMC0yMDEyQGV4
140 YW1wbGUuY29tMSkwJwYDVQQDEyBHb3N0UjM0MTAtMjAxMiAoMjU2IGJpdCkgZXhh
141 bXBsZYIBATAKBggqhQMHAQEDAgNBAF5bm4BbARR6hJLEoWJkOsYV3Hd7kXQQjz3C
142 dqQfmHrz6TI6Xojdh/t8ckODv/587NS5/6KsM77vc6Wh90NAT2s=
144 prv_key_raw = hexdec("BFCF1D623E5CDD3032A7C6EABB4A923C46E43D640FFEAAF2C3ED39A8FA399924")[::-1]
146 "id-GostR3410-2001-CryptoPro-XchA-ParamSet",
154 cert_raw = b64decode("""
155 MIIC6DCCAlSgAwIBAgIBATAKBggqhQMHAQEDAzBWMSkwJwYJKoZIhvcNAQkBFhpH
156 b3N0UjM0MTAtMjAxMkBleGFtcGxlLmNvbTEpMCcGA1UEAxMgR29zdFIzNDEwLTIw
157 MTIgKDUxMiBiaXQpIGV4YW1wbGUwHhcNMTMxMDA0MDczNjA0WhcNMzAxMDAxMDcz
158 NjA0WjBWMSkwJwYJKoZIhvcNAQkBFhpHb3N0UjM0MTAtMjAxMkBleGFtcGxlLmNv
159 bTEpMCcGA1UEAxMgR29zdFIzNDEwLTIwMTIgKDUxMiBiaXQpIGV4YW1wbGUwgaow
160 IQYIKoUDBwEBAQIwFQYJKoUDBwECAQICBggqhQMHAQECAwOBhAAEgYATGQ9VCiM5
161 FRGCQ8MEz2F1dANqhaEuywa8CbxOnTvaGJpFQVXQwkwvLFAKh7hk542vOEtxpKtT
162 CXfGf84nRhMH/Q9bZeAc2eO/yhxrsQhTBufa1Fuou2oe/jUOaG6RAtUUvRzhNTpp
163 RGGl1+EIY2vzzUua9j9Ol/gAoy/LNKQIfqOBwDCBvTAdBgNVHQ4EFgQUPcbTRXJZ
164 nHtjj+eBP7b5lcTMekIwCwYDVR0PBAQDAgHGMA8GA1UdEwQIMAYBAf8CAQEwfgYD
165 VR0BBHcwdYAUPcbTRXJZnHtjj+eBP7b5lcTMekKhWqRYMFYxKTAnBgkqhkiG9w0B
166 CQEWGkdvc3RSMzQxMC0yMDEyQGV4YW1wbGUuY29tMSkwJwYDVQQDEyBHb3N0UjM0
167 MTAtMjAxMiAoNTEyIGJpdCkgZXhhbXBsZYIBATAKBggqhQMHAQEDAwOBgQBObS7o
168 ppPTXzHyVR1DtPa8b57nudJzI4czhsfeX5HDntOq45t9B/qSs8dC6eGxbhHZ9zCO
169 SFtxWYdmg0au8XI9Xb8vTC1qdwWID7FFjMWDNQZb6lYh/J+8F2xKylvB5nIlRZqO
170 o3eUNFkNyHJwQCk2WoOlO16zwGk2tdKH4KmD5w==
172 prv_key_raw = hexdec("3FC01CDCD4EC5F972EB482774C41E66DB7F380528DFE9E67992BA05AEE462435757530E641077CE587B976C8EEB48C48FD33FD175F0C7DE6A44E014E6BCB074B")[::-1]
174 "id-tc26-gost-3410-12-512-paramSetB",
182 @skipIf(not pyderasn_exists, "PyDERASN dependency is required")
183 class TestRFC4491bis(TestCase):
184 """Test vectors from https://tools.ietf.org/html/draft-deremin-rfc4491-bis-02
203 prv_raw = hexdec(prv_hex)[::-1]
204 prv = prv_unmarshal(prv_raw)
205 curve = CURVES[curve_name]
206 pub = public_key(curve, prv)
207 pub_raw = pub_marshal(pub, mode=mode)
208 subj = Name(("rdnSequence", RDNSequence([
209 RelativeDistinguishedName((
210 AttributeTypeAndValue((
211 ("type", AttributeType(id_at_commonName)),
212 ("value", AttributeValue(PrintableString("Example"))),
216 spki = SubjectPublicKeyInfo((
217 ("algorithm", ai_spki),
218 ("subjectPublicKey", BitString(OctetString(pub_raw).encode())),
221 # Certification request
222 cri = CertificationRequestInfo((
223 ("version", Integer(0)),
225 ("subjectPKInfo", spki),
226 ("attributes", Attributes()),
228 sign = hexdec(cr_sign_hex)
229 self.assertTrue(verify(
232 hsh(cri.encode()).digest()[::-1],
236 cr = CertificationRequest((
237 ("certificationRequestInfo", cri),
238 ("signatureAlgorithm", ai_sign),
239 ("signature", BitString(sign)),
241 self.assertSequenceEqual(cr.encode(), b64decode(cr_b64))
244 tbs = TBSCertificate((
245 ("version", Version("v3")),
246 ("serialNumber", CertificateSerialNumber(cert_serial)),
247 ("signature", ai_sign),
249 ("validity", Validity((
250 ("notBefore", Time(("utcTime", UTCTime(b"010101000000Z")))),
251 ("notAfter", Time(("generalTime", GeneralizedTime(b"20501231000000Z")))),
254 ("subjectPublicKeyInfo", spki),
255 ("extensions", Extensions((
257 ("extnID", id_ce_basicConstraints),
258 ("critical", Boolean(True)),
259 ("extnValue", OctetString(
260 BasicConstraints((("cA", Boolean(True)),)).encode()
265 sign = hexdec(c_sign_hex)
266 self.assertTrue(verify(
269 hsh(tbs.encode()).digest()[::-1],
274 ("tbsCertificate", tbs),
275 ("signatureAlgorithm", ai_sign),
276 ("signatureValue", BitString(sign)),
278 self.assertSequenceEqual(cert.encode(), b64decode(c_b64))
282 ("version", Version("v2")),
283 ("signature", ai_sign),
285 ("thisUpdate", Time(("utcTime", UTCTime(b"140101000000Z")))),
286 ("nextUpdate", Time(("utcTime", UTCTime(b"140102000000Z")))),
288 sign = hexdec(crl_sign_hex)
289 self.assertTrue(verify(
292 hsh(tbs.encode()).digest()[::-1],
296 crl = CertificateList((
297 ("tbsCertList", tbs),
298 ("signatureAlgorithm", ai_sign),
299 ("signatureValue", BitString(sign)),
301 self.assertSequenceEqual(crl.encode(), b64decode(crl_b64))
303 def test_256_test_paramset(self):
305 "id-GostR3410-2001-TestParamSet",
308 AlgorithmIdentifier((
309 ("algorithm", id_tc26_gost3410_2012_256),
311 GostR34102012PublicKeyParameters((
312 ("publicKeyParamSet", id_GostR3410_2001_TestParamSet),
313 ("digestParamSet", id_tc26_gost3411_2012_256),
317 AlgorithmIdentifier((
318 ("algorithm", id_tc26_signwithdigest_gost3410_2012_256),
321 "7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE1D19CE9891EC3B28",
322 "6AAAB38E35D4AAA517940301799122D855484F579F4CBB96D63CDFDF3ACC432A41AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC0493",
324 MIHTMIGBAgEAMBIxEDAOBgNVBAMTB0V4YW1wbGUwZjAfBggqhQMHAQEBATATBgcq
325 hQMCAiMABggqhQMHAQECAgNDAARAC9hv5djbiWaPeJtOHbqFhcVQi0XsW1nYkG3b
326 cOJJK3/ad/+HGhD73ydm0pPF0WSvuzx7lzpByIXRHXDWibTxJqAAMAoGCCqFAwcB
327 AQMCA0EAaqqzjjXUqqUXlAMBeZEi2FVIT1efTLuW1jzf3zrMQypBqijS8asUgoDN
328 ntVv7aQZdAU1VKQnZ7g60EP9OdwEkw==
330 "4D53F012FE081776507D4D9BB81F00EFDB4EEFD4AB83BAC4BACF735173CFA81C41AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC0493",
332 MIIBLTCB26ADAgECAgEKMAoGCCqFAwcBAQMCMBIxEDAOBgNVBAMTB0V4YW1wbGUw
333 IBcNMDEwMTAxMDAwMDAwWhgPMjA1MDEyMzEwMDAwMDBaMBIxEDAOBgNVBAMTB0V4
334 YW1wbGUwZjAfBggqhQMHAQEBATATBgcqhQMCAiMABggqhQMHAQECAgNDAARAC9hv
335 5djbiWaPeJtOHbqFhcVQi0XsW1nYkG3bcOJJK3/ad/+HGhD73ydm0pPF0WSvuzx7
336 lzpByIXRHXDWibTxJqMTMBEwDwYDVR0TAQH/BAUwAwEB/zAKBggqhQMHAQEDAgNB
337 AE1T8BL+CBd2UH1Nm7gfAO/bTu/Uq4O6xLrPc1Fzz6gcQaoo0vGrFIKAzZ7Vb+2k
338 GXQFNVSkJ2e4OtBD/TncBJM=
340 "42BF392A14D3EBE957AF3E46CB50BF5F4221A003AD3D172753C94A9C37A31D2041AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC0493",
342 MIGSMEECAQEwCgYIKoUDBwEBAwIwEjEQMA4GA1UEAxMHRXhhbXBsZRcNMTQwMTAx
343 MDAwMDAwWhcNMTQwMTAyMDAwMDAwWjAKBggqhQMHAQEDAgNBAEK/OSoU0+vpV68+
344 RstQv19CIaADrT0XJ1PJSpw3ox0gQaoo0vGrFIKAzZ7Vb+2kGXQFNVSkJ2e4OtBD
349 def test_256a_paramset(self):
351 "id-tc26-gost-3410-2012-256-paramSetA",
354 AlgorithmIdentifier((
355 ("algorithm", id_tc26_gost3410_2012_256),
357 GostR34102012PublicKeyParameters((
358 ("publicKeyParamSet", id_tc26_gost3410_2012_256_paramSetA),
362 AlgorithmIdentifier((
363 ("algorithm", id_tc26_signwithdigest_gost3410_2012_256),
366 "7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE1D19CE9891EC3B28",
367 "1BDC2A1317679B66232F63EA16FF7C64CCAAB9AD855FC6E18091661DB79D48121D0E1DA5BE347C6F1B5256C7AEAC200AD64AC77A6F5B3A0E097318E7AE6EE769",
369 MIHKMHkCAQAwEjEQMA4GA1UEAxMHRXhhbXBsZTBeMBcGCCqFAwcBAQEBMAsGCSqF
370 AwcBAgEBAQNDAARAdCeV1L7ohN3yhQ/sA+o/rxhE4B2dpgtkUJOlXibfw5l49ZbP
371 TU0MbPHRiUPZRJPRa57AoW1RLS4SfMRpGmMY4qAAMAoGCCqFAwcBAQMCA0EAG9wq
372 Exdnm2YjL2PqFv98ZMyqua2FX8bhgJFmHbedSBIdDh2lvjR8bxtSVseurCAK1krH
375 "140B4DA9124B09CB0D5CE928EE874273A310129492EC0E29369E3B791248578C1D0E1DA5BE347C6F1B5256C7AEAC200AD64AC77A6F5B3A0E097318E7AE6EE769",
377 MIIBJTCB06ADAgECAgEKMAoGCCqFAwcBAQMCMBIxEDAOBgNVBAMTB0V4YW1wbGUw
378 IBcNMDEwMTAxMDAwMDAwWhgPMjA1MDEyMzEwMDAwMDBaMBIxEDAOBgNVBAMTB0V4
379 YW1wbGUwXjAXBggqhQMHAQEBATALBgkqhQMHAQIBAQEDQwAEQHQnldS+6ITd8oUP
380 7APqP68YROAdnaYLZFCTpV4m38OZePWWz01NDGzx0YlD2UST0WuewKFtUS0uEnzE
381 aRpjGOKjEzARMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoUDBwEBAwIDQQAUC02pEksJ
382 yw1c6Sjuh0JzoxASlJLsDik2njt5EkhXjB0OHaW+NHxvG1JWx66sIArWSsd6b1s6
385 "14BD68087C3B903C7AA28B07FEB2E7BD6FE0963F563267359F5CD8EAB45059AD1D0E1DA5BE347C6F1B5256C7AEAC200AD64AC77A6F5B3A0E097318E7AE6EE769",
387 MIGSMEECAQEwCgYIKoUDBwEBAwIwEjEQMA4GA1UEAxMHRXhhbXBsZRcNMTQwMTAx
388 MDAwMDAwWhcNMTQwMTAyMDAwMDAwWjAKBggqhQMHAQEDAgNBABS9aAh8O5A8eqKL
389 B/6y571v4JY/VjJnNZ9c2Oq0UFmtHQ4dpb40fG8bUlbHrqwgCtZKx3pvWzoOCXMY
394 def test_512_test_paramset(self):
396 "id-tc26-gost-3410-2012-512-paramSetTest",
399 AlgorithmIdentifier((
400 ("algorithm", id_tc26_gost3410_2012_512),
402 GostR34102012PublicKeyParameters((
403 ("publicKeyParamSet", id_tc26_gost3410_2012_512_paramSetTest),
407 AlgorithmIdentifier((
408 ("algorithm", id_tc26_signwithdigest_gost3410_2012_512),
411 "0BA6048AADAE241BA40936D47756D7C93091A0E8514669700EE7508E508B102072E8123B2200A0563322DAD2827E2714A2636B7BFD18AADFC62967821FA18DD4",
412 "433B1D6CE40A51F1E5737EB16AA2C683829A405B9D9127E21260FC9D6AC05D87BF24E26C45278A5C2192A75BA94993ABD6074E7FF1BF03FD2F5397AFA1D945582F86FA60A081091A23DD795E1E3C689EE512A3C82EE0DCC2643C78EEA8FCACD35492558486B20F1C9EC197C90699850260C93BCBCD9C5C3317E19344E173AE36",
414 MIIBTzCBvAIBADASMRAwDgYDVQQDEwdFeGFtcGxlMIGgMBcGCCqFAwcBAQECMAsG
415 CSqFAwcBAgECAAOBhAAEgYDh7zDVLGEz3dmdHVxBRVz3302LTJJbvGmvFDPRVlhR
416 Wt0hRoUMMlxbgcEzvmVaqMTUQOe5io1ZSHsMdpa8xV0R7L53NqnsNX/y/TmTH04R
417 TLjNo1knCsfw5/9D2UGUGeph/Sq3f12fY1I9O1CgT2PioM9Rt8E63CFWDwvUDMnH
418 N6AAMAoGCCqFAwcBAQMDA4GBAEM7HWzkClHx5XN+sWqixoOCmkBbnZEn4hJg/J1q
419 wF2HvyTibEUnilwhkqdbqUmTq9YHTn/xvwP9L1OXr6HZRVgvhvpgoIEJGiPdeV4e
420 PGie5RKjyC7g3MJkPHjuqPys01SSVYSGsg8cnsGXyQaZhQJgyTvLzZxcMxfhk0Th
423 "415703D892F1A5F3F68C4353189A7EE207B80B5631EF9D49529A4D6B542C2CFA15AA2EACF11F470FDE7D954856903C35FD8F955EF300D95C77534A724A0EEE702F86FA60A081091A23DD795E1E3C689EE512A3C82EE0DCC2643C78EEA8FCACD35492558486B20F1C9EC197C90699850260C93BCBCD9C5C3317E19344E173AE36",
425 MIIBqjCCARagAwIBAgIBCzAKBggqhQMHAQEDAzASMRAwDgYDVQQDEwdFeGFtcGxl
426 MCAXDTAxMDEwMTAwMDAwMFoYDzIwNTAxMjMxMDAwMDAwWjASMRAwDgYDVQQDEwdF
427 eGFtcGxlMIGgMBcGCCqFAwcBAQECMAsGCSqFAwcBAgECAAOBhAAEgYDh7zDVLGEz
428 3dmdHVxBRVz3302LTJJbvGmvFDPRVlhRWt0hRoUMMlxbgcEzvmVaqMTUQOe5io1Z
429 SHsMdpa8xV0R7L53NqnsNX/y/TmTH04RTLjNo1knCsfw5/9D2UGUGeph/Sq3f12f
430 Y1I9O1CgT2PioM9Rt8E63CFWDwvUDMnHN6MTMBEwDwYDVR0TAQH/BAUwAwEB/zAK
431 BggqhQMHAQEDAwOBgQBBVwPYkvGl8/aMQ1MYmn7iB7gLVjHvnUlSmk1rVCws+hWq
432 LqzxH0cP3n2VSFaQPDX9j5Ve8wDZXHdTSnJKDu5wL4b6YKCBCRoj3XleHjxonuUS
433 o8gu4NzCZDx47qj8rNNUklWEhrIPHJ7Bl8kGmYUCYMk7y82cXDMX4ZNE4XOuNg==
435 "3A13FB7AECDB5560EEF6137CFC5DD64691732EBFB3690A1FC0C7E8A4EEEA08307D648D4DC0986C46A87B3FBE4C7AF42EA34359C795954CA39FF3ABBED9051F4D2F86FA60A081091A23DD795E1E3C689EE512A3C82EE0DCC2643C78EEA8FCACD35492558486B20F1C9EC197C90699850260C93BCBCD9C5C3317E19344E173AE36",
437 MIHTMEECAQEwCgYIKoUDBwEBAwMwEjEQMA4GA1UEAxMHRXhhbXBsZRcNMTQwMTAx
438 MDAwMDAwWhcNMTQwMTAyMDAwMDAwWjAKBggqhQMHAQEDAwOBgQA6E/t67NtVYO72
439 E3z8XdZGkXMuv7NpCh/Ax+ik7uoIMH1kjU3AmGxGqHs/vkx69C6jQ1nHlZVMo5/z
440 q77ZBR9NL4b6YKCBCRoj3XleHjxonuUSo8gu4NzCZDx47qj8rNNUklWEhrIPHJ7B
441 l8kGmYUCYMk7y82cXDMX4ZNE4XOuNg==