PyDERASN: මම තව් සහ බ්ලොබ් සහිත ASN.1 පුස්තකාලයක් ලිවූ ආකාරය

ASN.1 මෙය ව්‍යුහගත තොරතුරු විස්තර කරන භාෂාවක සම්මතයක් (ISO, ITU-T, GOST) මෙන්ම මෙම තොරතුරු කේතනය කිරීමේ නීතිරීති වේ. මට නම්, ක්‍රමලේඛකයෙකු ලෙස, මෙය JSON, XML, XDR සහ වෙනත් අය සමඟ දත්ත අනුක්‍රමික සහ ඉදිරිපත් කිරීමේ තවත් ආකෘතියක් පමණි. එය අපගේ එදිනෙදා ජීවිතයේදී අතිශයින් සුලභ වන අතර, බොහෝ අය එය මුණගැසෙන්නේ: සෙලියුලර්, දුරකථන, VoIP සන්නිවේදනයන් (UMTS, LTE, WiMAX, SS7, H.323), ජාල ප්‍රොටෝකෝල (LDAP, SNMP, Kerberos), සෑම දෙයකම බැංකු කාඩ්පත් සහ ජෛවමිතික ගමන් බලපත්‍රවල ගුප්ත ලේඛන (X.509, CMS, PKCS ප්‍රමිති), සහ තවත් බොහෝ දේ ගැන සැලකිලිමත් වේ.

මෙම ලිපිය සමඟ කටයුතු කරයි PyDERASN: Python ASN.1 පුස්තකාලය ක්‍රිප්ටෝග්‍රැෆි සම්බන්ධ ව්‍යාපෘති වල සක්‍රියව භාවිතා වේ ඇට්ලස්.

PyDERASN: මම තව් සහ බ්ලොබ් සහිත ASN.1 පුස්තකාලයක් ලිවූ ආකාරය
සාමාන්යයෙන්, ASN.1 ගුප්ත ලේඛන කාර්යයන් සඳහා නිර්දේශ කිරීම වටී නැත: ASN.1 සහ එහි කෝඩෙක්ස් සංකීර්ණ වේ. මෙයින් අදහස් කරන්නේ කේතය සරල නොවන අතර මෙය සැමවිටම අතිරේක ප්රහාරක දෛශිකයකි. නිකමට බලන්න ලැයිස්තුවට ASN.1 පුස්තකාලවල දුර්වලතා. Bruce Schneier ඔහුගේ ගුප්ත ලේඛන ඉංජිනේරු මෙම ප්‍රමිතිය එහි සංකීර්ණත්වය හේතුවෙන් භාවිතා කිරීමට එරෙහිව ද උපදෙස් දෙයි: "හොඳම ප්‍රසිද්ධ TLV කේතනය ASN.1, නමුත් එය ඇදහිය නොහැකි තරම් සංකීර්ණ වන අතර අපි එයින් ඉවත් වෙමු." එහෙත්, අවාසනාවකට මෙන්, අද අපට තිබේ පොදු යතුරු යටිතල පහසුකම් ඔවුන් ක්රියාශීලීව භාවිතා කරන X.509 සහතික, CRL, OCSP, TSP, CMP ප්‍රොටෝකෝල, නගර සභාව, පණිවිඩ CMS, සහ බොහෝ ප්රමිති PKCS. එබැවින්, ඔබ ගුප්තකේතනයට සම්බන්ධ ඕනෑම දෙයක් කරන්නේ නම්, ඔබට ASN.1 සමඟ වැඩ කිරීමට හැකි විය යුතුය.

ASN.1 විවිධ ආකාරවලින්/කෝඩෙක්ස් වලින් කේතනය කළ හැක:

  • බර් (මූලික කේතන රීති)
  • CER (කැනොනිකල් කේතන රීති)
  • DER (විශිෂ්ට කේතීකරණ රීති)
  • GSER (සාමාන්‍ය තන්තු කේතන රීති)
  • JER (JSON කේතන රීති)
  • LWER (සැහැල්ලු බර කේතන නීති)
  • REO (ඔක්ටෙට් කේතන රීති)
  • එක් (ඇසුරුම් කේතන රීති)
  • SER (නිශ්චිත කේතීකරණ රීති සංඥා කිරීම)
  • ගෝලයන් (XML කේතන රීති)

සහ තවත් ගණනාවක්. නමුත් ගුප්ත ලේඛන කාර්යයන් වලදී, ප්රායෝගිකව, දෙකක් භාවිතා වේ: BER සහ DER. අත්සන් කළ XML ලේඛනවල පවා (XMLDSig, XAdES) JSON-නැඹුරු ප්‍රොටෝකෝලයේ මෙන් Base64-කේතනය කරන ලද ASN.1 DER වස්තු තවමත් පවතිනු ඇත. acme Let's Encrypt වෙතින්. ඔබට මෙම සියලුම කෝඩෙක්ස් සහ BER/CER/DER කේතීකරණ මූලධර්ම ලිපි සහ පොත්වල වඩා හොඳින් අවබෝධ කර ගත හැක: ASN.1 සරල වචන වලින්, ASN.1 - ඔලිවියර් ඩුබිසන් විසින් විෂමජාතීය පද්ධති අතර සන්නිවේදනය, ASN.1 මහාචාර්ය John Larmouth විසින් සම්පූර්ණ කරන ලදී.

BER යනු ද්විමය බයිට්-නැඹුරු (උදාහරණයක් ලෙස PER, සෙලියුලර් සන්නිවේදනයේ ජනප්‍රිය - බිටු-නැඹුරු) TLV ආකෘතියකි. සෑම මූලද්‍රව්‍යයක්ම මෙසේ කේතනය කර ඇත: ටැගය (Tag), කේතනය කළ යුතු මූලද්‍රව්‍ය වර්ගය හඳුනා ගැනීම (පූර්ණ සංඛ්‍යාව, නූල්, දිනය, ආදිය), දිග (Lදිග) අන්තර්ගතය සහ අන්තර්ගතය ම (Valu) BER විකල්ප වශයෙන් ඔබට විශේෂ අවිනිශ්චිත දිග අගයක් සැකසීමෙන් සහ Octets අවසානයට යන පණිවිඩය අවසානයේ Octets ලකුණකින් අවසන් කිරීමෙන් දිග අගයක් සඳහන් නොකිරීමට ඉඩ දෙයි. දිග කේතනයට අමතරව, BER හට දත්ත වර්ග කේතනය කරන ආකාරයෙහි බොහෝ විචල්‍යයන් ඇත, එනම්:

  • INTEGER, OBJECT IDENTIFIER, BIT STRING සහ මූලද්‍රව්‍ය දිග සාමාන්‍යකරණය නොකළ හැකිය (අවම ආකාරයෙන් කේතනය කර නැත);
  • BOOLEAN ශුන්‍ය නොවන ඕනෑම අන්තර්ගතයක් සඳහා සත්‍ය වේ;
  • BIT STRING හි "අතිරේක" බිටු අඩංගු විය හැක;
  • BIT STRING, OCTET STRING සහ ඒවායේ සියලුම ව්‍යුත්පන්න තන්තු වර්ග, දිනය/වේලාව ඇතුළුව, විචල්‍ය-දිග කැබලිවලට කැඩිය හැක, (de)කේතනය කරන අවස්ථාවේදී එහි දිග කල්තියා නොදනී;
  • UTCTtime/GeneralizedTime හට කාල කලාප ඕෆ්සෙට් සහ තත්පර වල "අතිරේක" ශුන්‍ය භාග නියම කිරීමට විවිධ ක්‍රම තිබිය හැක;
  • පෙරනිමි අනුක්‍රමික අගයන් කේතනය කළ හැකි හෝ නොවිය හැක;
  • BIT STRING හි අවසාන බිටු වල නම් කරන ලද අගයන් විකල්ප වශයෙන් සංකේතනය නොකළ හැක;
  • SEQUENCE (OF)/SET (OF) හට ඕනෑම මූලද්‍රව්‍ය අනුපිළිවෙලක් තිබිය හැක.

ඉහත සියල්ල නිසා, දත්ත මුල් ආකෘතියට සමාන වන පරිදි කේතනය කිරීම සැමවිටම කළ නොහැක. එබැවින්, නීතිවල උප කුලකයක් සොයා ගන්නා ලදී: DER - එක් වලංගු කේතීකරණ ක්‍රමයක් පමණක් දැඩි ලෙස නියාමනය කිරීම, එය ගුප්ත ලේඛන කාර්යයන් සඳහා ඉතා වැදගත් වන අතර, උදාහරණයක් ලෙස, එක් බිට් එකක් වෙනස් කිරීම අත්සන හෝ චෙක්සම් වලංගු නොවේ. DER හට සැලකිය යුතු අවාසියක් ඇත: දත්ත ප්‍රවාහ අනුක්‍රමිකකරණයට ඉඩ නොදෙන කේතීකරණ වේලාවේදී සියලුම මූලද්‍රව්‍යවල දිග කල්තියා දැනගත යුතුය. CER codec හි මෙම අඩුපාඩුවක් නොමැත, ඒ හා සමානව දත්තවල නිරවුල් නියෝජනයක් සහතික කරයි. අවාසනාවකට (නැතහොත් ඊටත් වඩා සංකීර්ණ විකේතක නොමැති වීම වාසනාවක්ද?), එය ජනප්‍රිය වූයේ නැත. එබැවින්, ප්‍රායෝගිකව අපට BER සහ DER සංකේතිත දත්තවල "මිශ්‍ර" භාවිතයක් හමු වේ. CER සහ DER යන දෙකම BER හි උප කුලකයක් වන බැවින්, ඕනෑම BER විකේතකයෙකුට ඒවා හැසිරවිය හැක.

pyasn1 සමඟ ගැටළු

වැඩ කරනකොට අපි cryptography වලට අදාල Python වැඩසටහන් ගොඩක් ලියනවා. මීට වසර කිහිපයකට පෙර ප්‍රායෝගිකව නොමිලේ පුස්තකාල තෝරා ගැනීමක් නොතිබුණි: එක්කෝ මේවා ඔබට සරලව කේතනය කිරීමට/විකේතනය කිරීමට ඉඩ සලසන ඉතා පහත් මට්ටමේ පුස්තකාල වේ, උදාහරණයක් ලෙස, පූර්ණ සංඛ්‍යාවක් සහ ව්‍යුහ ශීර්ෂයක් හෝ මෙම පුස්තකාලය pyasn1. අපි එය මත වසර කිහිපයක් ජීවත් වූ අතර මුලදී අපි ඉතා සතුටු විය, එය ඔබට ඉහළ මට්ටමේ වස්තූන් සමඟ ASN.1 ව්‍යුහයන් සමඟ වැඩ කිරීමට ඉඩ සලසයි: උදාහරණයක් ලෙස, විකේතනය කළ X.509 සහතික වස්තුවක් මඟින් එහි ක්ෂේත්‍ර වෙත ප්‍රවේශ වීමට ඔබට ඉඩ සලසයි. ශබ්ද කෝෂ අතුරුමුහුණත: cert[“tbsCertificate”] ["serialNumber"] මෙම සහතිකයේ අනුක්‍රමික අංකය අපට පෙන්වයි. ඒ හා සමානව, ඔබට සංකීර්ණ වස්තූන් ලැයිස්තු, ශබ්දකෝෂ ලෙස වැඩ කිරීමෙන් "එකලස්" කළ හැකිය, ඉන්පසු සරලව pyasn1.codec.der.encoder.encode ශ්‍රිතය අමතා ලේඛනයේ අනුක්‍රමික නිරූපණයක් ලබා ගන්න.

කෙසේ වෙතත්, අඩුපාඩු, ගැටළු සහ සීමාවන් අනාවරණය විය. අවාසනාවකට මෙන්, pyasn1 හි දෝෂ ඇති අතර, තවමත් පවතී: ලියන අවස්ථාව වන විට, pyasn1 හි මූලික වර්ග වලින් එකක් වන්නේ GeneralizedTime, වැරදියට විකේතනය කර කේතනය කර ඇත.

අපගේ ව්‍යාපෘති වලදී, ඉඩ ඉතිරි කර ගැනීම සඳහා, අපි බොහෝ විට ගබඩා කරන්නේ අපට යොමු කිරීමට අවශ්‍ය වස්තුවේ ගොනු මාර්ගය, ඕෆ්සෙට් සහ දිග බයිට් වලින් පමණි. උදාහරණයක් ලෙස, අත්තනෝමතික ලෙස අත්සන් කරන ලද ගොනුවක් බොහෝ විට CMS SignedData ASN.1 ව්‍යුහය තුළ ස්ථානගත වනු ඇත:

  0     [1,3,1018]  ContentInfo SEQUENCE
  4     [1,1,   9]   . contentType: ContentType OBJECT IDENTIFIER 1.2.840.113549.1.7.2 (id_signedData)
 19-4   [0,0,1003]   . content: [0] EXPLICIT [UNIV 16] ANY
 19     [1,3, 999]   . . DEFINED BY id_signedData: SignedData SEQUENCE
 23     [1,1,   1]   . . . version: CMSVersion INTEGER v3 (03)
 26     [1,1,  19]   . . . digestAlgorithms: DigestAlgorithmIdentifiers SET OF
                           [...]
 47     [1,3, 769]   . . . encapContentInfo: EncapsulatedContentInfo SEQUENCE
 51     [1,1,   8]   . . . . eContentType: ContentType OBJECT IDENTIFIER 1.3.6.1.5.5.7.12.2 (id_cct_PKIData)
 65-4   [1,3, 751]   . . . . eContent: [0] EXPLICIT OCTET STRING 751 bytes OPTIONAL

                 ТУТ СОДЕРЖИМОЕ ПОДПИСЫВАЕМОГО ФАЙЛА РАЗМЕРОМ 751 байт

820     [1,2, 199]   . . . signerInfos: SignerInfos SET OF
823     [1,2, 196]   . . . . 0: SignerInfo SEQUENCE
826     [1,1,   1]   . . . . . version: CMSVersion INTEGER v3 (03)
829     [0,0,  22]   . . . . . sid: SignerIdentifier CHOICE subjectKeyIdentifier
                               [...]
956     [1,1,  64]   . . . . . signature: SignatureValue OCTET STRING 64 bytes
                     . . . . . . C1:B3:88:BA:F8:92:1C:E6:3E:41:9B:E0:D3:E9:AF:D8
                     . . . . . . 47:4A:8A:9D:94:5D:56:6B:F0:C1:20:38:D2:72:22:12
                     . . . . . . 9F:76:46:F6:51:5F:9A:8D:BF:D7:A6:9B:FD:C5:DA:D2
                     . . . . . . F3:6B:00:14:A4:9D:D7:B5:E1:A6:86:44:86:A7:E8:C9

සහ අපට මුල් අත්සන් කළ ගොනුව බයිට් 65ක්, බයිට් 751ක් දිග ඕෆ්සෙට් වලින් ලබා ගත හැක. pyasn1 මෙම තොරතුරු එහි විකේතනය කරන ලද වස්තූන් තුළ ගබඩා නොකරයි. ඊනියා TLVSeeker ලියා ඇත - ටැග් සහ වස්තු දිග විකේතනය කිරීමට ඔබට ඉඩ සලසන කුඩා පුස්තකාලයක්, එහි අතුරු මුහුණතේ අපි “ඊළඟ ටැගයට යන්න”, “ටැගය ඇතුළට යන්න” (SEQUENCE වස්තුව ඇතුළට යන්න) "ඊළඟ ටැගය වෙත යන්න", "ඔබේ ඕෆ්සෙට් සහ අප සිටින වස්තුවේ දිග කියන්න." මෙය ASN.1 DER අනුක්‍රමික දත්ත හරහා "අත්පොත" ඇවිදීමකි. නමුත් BER අනුක්‍රමික දත්ත සමඟ මේ ආකාරයෙන් වැඩ කිරීමට නොහැකි විය, මන්ද, උදාහරණයක් ලෙස, OCTET STRING බයිට් තන්තුව කුට්ටි කිහිපයක ස්වරූපයෙන් කේතනය කළ හැකි බැවිනි.

අපගේ pyasn1 කර්තව්‍යයන් සඳහා ඇති තවත් අවාසියක් නම්, ලබා දී ඇති ක්ෂේත්‍රයක් SEQUENCE තුළ තිබේද නැද්ද යන්න විකේතනය කරන ලද වස්තු වලින් තේරුම් ගැනීමට ඇති නොහැකියාවයි. උදාහරණයක් ලෙස, ව්‍යුහයේ Smth විකල්ප ක්ෂේත්‍රයේ ක්ෂේත්‍ර අනුපිළිවෙලක් තිබේ නම්, එය ලැබෙන දත්ත වලින් සම්පූර්ණයෙන්ම නොපැමිණීම (විකල්පමය), නැතහොත් එය පැවතිය හැකි නමුත් ශුන්‍ය දිගකින් (හිස් ලැයිස්තුව) විය හැකිය. පොදුවේ, මෙය තීරණය කළ නොහැකි විය. ලැබුණු දත්තවල වලංගුභාවය දැඩි ලෙස තහවුරු කිරීම සඳහා මෙය අවශ්ය වේ. ASN.1 යෝජනා ක්‍රමවල දෘෂ්ටි කෝණයෙන් "සම්පූර්ණයෙන්ම වලංගු නොවන" දත්ත සහිත සහතිකයක් සමහර සහතික කිරීමේ අධිකාරියක් නිකුත් කරනු ඇතැයි සිතන්න! උදාහරණයක් ලෙස, සහතික කිරීමේ අධිකාරිය "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı" එහි මූල සහතිකයේ අවසර ලත් සීමාවන් ඉක්මවා ඇත. RFC 5280 විෂය සංරචකයේ දිග මත සීමාවන් - එය යෝජනා ක්රමය අනුව අවංකව විකේතනය කළ නොහැක. DER codec මඟින් සම්ප්‍රේෂණය කිරීමේදී DEFAULT ට සමාන අගයක් ඇති ක්ෂේත්‍රයක් කේතනය නොකිරීමට අවශ්‍ය වේ - එවැනි ලේඛන ජීවිතයේ සිදු වේ, සහ PyDERASN හි පළමු අනුවාදය හිතාමතාම එවැනි වලංගු නොවන (DER දෘෂ්ටි කෝණයෙන්) හැසිරීමට ඉඩ දී ඇත. පසුගාමී ගැළපුම.

තවත් සීමාවක් වන්නේ ව්‍යුහය තුළ කිසියම් වස්තුවක් කේතනය කර ඇත්තේ කුමන ආකාරයෙන්ද (BER/DER) පහසුවෙන් සොයා ගැනීමට ඇති නොහැකියාවයි. උදාහරණයක් ලෙස, CMS ප්‍රමිතිය පවසන්නේ පණිවිඩය BER-කේතනය කර ඇති නමුත්, Cryptographic අත්සන ජනනය කර ඇති signedAttrs ක්ෂේත්‍රය DER හි තිබිය යුතු බවයි. අපි DER සමඟ විකේතනය කළහොත්, අපි CMS සැකසීමේදීම අසාර්ථක වනු ඇත; අපි BER සමඟ විකේතනය කළහොත්, අත්සන් කරන ලදAttrs කුමන ආකෘතියේ දැයි අපි නොදනිමු. මෙහි ප්‍රතිඵලයක් වශයෙන්, TLVSeeker හට (pyasn1 හි ප්‍රතිසමයක් නොමැති) අත්සන් කරන ලදAttrs ක්ෂේත්‍රවල පිහිටීම සෙවීමට සිදුවනු ඇති අතර, වෙන වෙනම, එය අනුක්‍රමික නිරූපණයෙන් ඉවත් කර, DER සමඟ විකේතනය කරන්න.

බොහෝ විට සිදු වන ක්ෂේත්‍ර මගින් නිර්වචනය කරන ලද ස්වයංක්‍රීයව සැකසීමේ හැකියාව අපට ඉතා අවශ්‍ය විය. ASN.1 ව්‍යුහය විකේතනය කිරීමෙන් පසුව, ව්‍යුහ ක්ෂේත්‍රයේ දක්වා ඇති OBJECT IDENTIFIER මත පදනම්ව තෝරාගත් යෝජනා ක්‍රමයට අනුව තවදුරටත් සැකසිය යුතු බොහෝ ක්ෂේත්‍ර අපට ඉතිරි විය හැක. පයිතන් කේතයේ, මෙයින් අදහස් කරන්නේ නම් ලිවීම සහ ඕනෑම ක්ෂේත්‍රයක් සඳහා විකේතකය ඇමතීමයි.

PyDERASN හි මතුවීම

ඇට්ලස් හිදී, අපි යම් යම් ගැටළු ඇති විට හෝ අප භාවිතා කරන නොමිලේ වැඩසටහන් වැඩිදියුණු කරන විට අපි නිතිපතා පැච් ඉහළට යවමු. අපි pyasn1 වෙත කිහිප වතාවක් වැඩි දියුණු කිරීම් ඉදිරිපත් කළ නමුත්, pyasn1 හි කේතය තේරුම් ගැනීමට පහසුම නොවන අතර සමහර විට අපව පරාජය කරන නොගැලපෙන API වෙනස්කම් තිබේ. ඊට අමතරව, අපි pyasn1 හි සිදු නොවූ ජනක පරීක්ෂණ සමඟ පරීක්ෂණ ලිවීමට පුරුදු වී සිටිමු.

හොඳ දවසක් මම තීරණය කළා මට මේක ප්‍රමාණවත් බව සහ __slot__s, offsets සහ ලස්සනට ප්‍රදර්ශනය කරන ලද blobs සමඟ මගේම පුස්තකාලයක් ලිවීමට උත්සාහ කිරීමට කාලයයි මේ! සරලව ASN.1 codec එකක් නිර්මාණය කිරීම ප්‍රමාණවත් නොවනු ඇත - අපි අපගේ සියලු යැපෙන ව්‍යාපෘති එයට මාරු කිරීමට අවශ්‍ය වන අතර, මේවා ASN.1 ව්‍යුහයන් සමඟ වැඩ කරන ලද කේත පේළි සිය දහස් ගණනක් වේ. එනම්, එය සඳහා වන එක් අවශ්යතාවක්: වත්මන් pyasn1 කේතය පරිවර්තනය කිරීමේ පහසුව. මගේ සියලු නිවාඩු කාලය ගත කළ මම මෙම පුස්තකාලය ලියා සියලු ව්‍යාපෘති එයට මාරු කළෙමි. ඔවුන් සතුව පරීක්ෂණ සමඟ 100% ක පමණ ආවරණයක් ඇති බැවින්, මෙයින් අදහස් කළේ පුස්තකාලය සම්පූර්ණයෙන්ම ක්‍රියාත්මක වූ බවයි.

PyDERASN, ඒ හා සමානව, 100% පරීක්ෂණ ආවරණයක් ඇත. විශිෂ්ට පුස්තකාලයක් සමඟ උත්පාදක පරීක්ෂණ භාවිතා කරයි කල්පිතය. එය ද සිදු කරන ලදී අවුල් සහගතයි py-afl- මම න්‍යෂ්ටික යන්ත්‍ර 32කින් කනවා. අපට ප්‍රායෝගිකව Python2 කේතයක් ඉතිරිව නොතිබුණද, PyDERASN තවමත් එය සමඟ ගැළපීමක් පවත්වා ගෙන යන අතර මේ නිසා ඇත්තේ එකම එකකි. හය ඇබ්බැහි වීම. එපමණක් නොව, එය එරෙහිව පරීක්ෂා කරනු ලැබේ ASN.1:2008 අනුකූලතා පරීක්ෂණ කට්ටලය.

එය සමඟ වැඩ කිරීමේ මූලධර්මය pyasn1 ට සමාන වේ - ඉහළ මට්ටමේ Python වස්තූන් සමඟ වැඩ කිරීම. ASN.1 යෝජනා ක්‍රමවල විස්තරය සමාන වේ.

class TBSCertificate(Sequence):
    schema = (
        ("version", Version(expl=tag_ctxc(0), default="v1")),
        ("serialNumber", CertificateSerialNumber()),
        ("signature", AlgorithmIdentifier()),
        ("issuer", Name()),
        ("validity", Validity()),
        ("subject", Name()),
        ("subjectPublicKeyInfo", SubjectPublicKeyInfo()),
        ("issuerUniqueID", UniqueIdentifier(impl=tag_ctxp(1), optional=True)),
        ("subjectUniqueID", UniqueIdentifier(impl=tag_ctxp(2), optional=True)),
        ("extensions", Extensions(expl=tag_ctxc(3), optional=True)),
    )

කෙසේ වෙතත්, PyDERASN සතුව ප්‍රබල ටයිප් කිරීමේ යම් සමානකමක් ඇත. pyasn1 හි, ක්ෂේත්‍රයක් CMSVersion(INTEGER) වර්ගයේ නම්, එය int හෝ INTEGER ලෙස පැවරිය හැක. PyDERASN හට පවරන ලද වස්තුව හරියටම CMSVersion වීම අවශ්‍ය වේ. Python3 කේතය ලිවීමට අමතරව, අපි භාවිතා කරමු විවරණ ටයිප් කිරීම, එබැවින් අපගේ ශ්‍රිතවලට def func(serial, contents) වැනි අපැහැදිලි තර්ක නොමැත, නමුත් def func(serial: CertificateSerialNumber, contents: EncapsulatedContentInfo), සහ PyDERASN එවැනි කේතයක් පවත්වා ගැනීමට උපකාරී වේ.

ඒ අතරම, PyDERASN හට මෙම ටයිප් කිරීම සඳහා අතිශයින්ම පහසු සහන ඇත. pyasn1 විසින් SubjectKeyIdentifier().subtype(implicitTag=Tag(...)) ක්ෂේත්‍රයට වස්තුවක් SubjectKeyIdentifier() වෙත පැවරීමට ඉඩ නොදුන් අතර (අවශ්‍ය IMPLICIT TAG නොමැතිව) බොහෝ විට වස්තු පිටපත් කර ප්‍රතිනිර්මාණය කිරීම අවශ්‍ය විය. වෙනස් කරන ලද IMPLICIT/ExplICIT ටැග්. PyDERASN පාදක වර්ගය පමණක් දැඩිව නිරීක්ෂණය කරයි - එය ව්‍යුහයේ දැනටමත් පවතින ASN.1 schema වෙතින් ටැග් ස්වයංක්‍රීයව ආදේශ කරනු ඇත. මෙය යෙදුම් කේතය බෙහෙවින් සරල කරයි.

විකේතනය කිරීමේදී දෝෂයක් සිදුවුවහොත්, pyasn1 හි එය හරියටම සිදුවූයේ කොතැනද යන්න තේරුම් ගැනීම පහසු නැත. උදාහරණයක් ලෙස, ඉහත දැනටමත් සඳහන් කර ඇති තුර්කි සහතිකයේ, අපට පහත දෝෂය ලැබෙනු ඇත: UTF8String (tbsCertificate:issuer:rdnSequence:3:0:value:defined by 2.5.4.10:utf8String) (138 දී) අසතුටුදායක සීමාවන්: 1 ⇐ ⇐ 77 ASN .64 ව්‍යුහයන් ලිවීමේදී පුද්ගලයන්ට වැරදි සිදු විය හැකි අතර, මෙය යෙදුම් දෝශ නිරාකරණය කිරීම හෝ අනෙක් පාර්ශ්වයේ කේත ලේඛන සමඟ ගැටලු හඳුනා ගැනීම පහසු කරයි.

PyDERASN හි පළමු අනුවාදය BER කේතනයට සහය නොදැක්වීය. එය බොහෝ කලකට පසුව දර්ශනය වූ අතර තවමත් කාල කලාප සමඟ UTCTime/GeneralizedTime සැකසීමට සහාය නොදක්වයි. මෙය අනාගතයේදී පැමිණෙනු ඇත, මන්ද මෙම ව්යාපෘතිය ප්රධාන වශයෙන් මගේ නිදහස් කාලය තුළ ලියා ඇත.

එසේම, පළමු අනුවාදයේ ක්ෂේත්‍ර මගින් අර්ථ දක්වා ඇති කාර්යයක් නොමැත. මාස කිහිපයකට පසු මෙය අවස්ථාව උදා විය සහ සක්‍රීයව භාවිතා කිරීමට පටන් ගත් අතර, යෙදුම් කේතය සැලකිය යුතු ලෙස අඩු කරයි - එක් විකේතන මෙහෙයුමකදී සම්පූර්ණ ව්‍යුහයම ගැඹුරට විසුරුවා හැරීමට හැකි විය. මෙය සිදු කිරීම සඳහා, ක්‍රමලේඛනය "නිර්වචනය" කරන්නේ කුමන ක්ෂේත්‍රද යන්න නියම කරයි. උදාහරණයක් ලෙස, CMS යෝජනා ක්රමය පිළිබඳ විස්තරයක්:

class ContentInfo(Sequence):
    schema = (
        ("contentType", ContentType(defines=((("content",), {
            id_authenticatedData: AuthenticatedData(),
            id_digestedData: DigestedData(),
            id_encryptedData: EncryptedData(),
            id_envelopedData: EnvelopedData(),
            id_signedData: SignedData(),
        }),))),
        ("content", Any(expl=tag_ctxc(0))),
    )

ContentType හි id_signedData අගය සහිත OID එකක් තිබේ නම්, SignedData යෝජනා ක්‍රමයට අනුව අන්තර්ගත ක්ෂේත්‍රය (එකම SEQUENCE තුළ පිහිටා ඇත) විකේතනය කළ යුතු බව පවසයි. මෙතරම් වරහන් ඇත්තේ ඇයි? EnvelopedData ව්‍යුහයන්හි ඇති පරිදි ක්ෂේත්‍රයකට ක්ෂේත්‍ර කිහිපයක් එකවර "නිර්වචනය" කළ හැක. නිර්වචනය කරන ලද ක්ෂේත්ර හඳුනාගනු ලබන්නේ ඊනියා විකේතන මාර්ගයෙනි - එය සියලු ව්යුහයන් තුළ ඕනෑම මූලද්රව්යයක නිශ්චිත ස්ථානය නියම කරයි.

ඔබට මෙම නිර්වචන වහාම රූප සටහනට එක් කිරීමට ඔබට සැමවිටම අවශ්‍ය නැත හෝ සෑම විටම අවස්ථාවක් නොමැත. OIDs සහ ව්‍යුහයන් තෙවන පාර්ශ්ව ව්‍යාපෘතියක පමණක් දන්නා විට යෙදුම්-විශේෂිත අවස්ථා තිබිය හැක. PyDERASN ව්‍යුහය විකේතනය කරන අවස්ථාවේදීම මෙම නිර්වචන සැකසීමේ හැකියාව සපයයි:

ContentInfo().decode(data, ctx={"defines_by_path": ((
    (
        "content", DecodePathDefBy(id_signedData),
        "certificates", any, "certificate", "tbsCertificate",
        "extensions", any, "extnID",
    ),
    ((("extnValue",), {
        id_ce_authorityKeyIdentifier: AuthorityKeyIdentifier(),
        id_ce_basicConstraints: BasicConstraints(),
        [...]
        id_ru_subjectSignTool: SubjectSignTool(),
    }),),
),)})

මෙන්න අපි කියනවා CMS SignedData හි අමුණා ඇති සියලුම සහතික සඳහා, ඒවායේ සියලුම දිගු විකේතනය කරන්න (AuthorityKeyIdentifier, BasicConstraints, SubjectSignTool, ආදිය). නිර්වචනය සමඟ “ආදේශ කළ යුතු” මූලද්‍රව්‍ය ක්‍රමලේඛනයේ දක්වා ඇති ආකාරයට අපි විකේතන මාර්ගය හරහා දක්වන්නෙමු.

අවසාන වශයෙන්, PyDERASN වෙතින් ධාවනය කිරීමේ හැකියාව ඇත විධාන රේඛාව ASN.1 ගොනු විකේතනය කිරීම සඳහා සහ පොහොසත් ඇත ලස්සන මුද්රණය. ඔබට අත්තනෝමතික ASN.1 විකේතනය කළ හැකිය, නැතහොත් ඔබට පැහැදිලිව අර්ථ දක්වා ඇති යෝජනා ක්‍රමයක් සඳහන් කර මෙවැනි දෙයක් දැකිය හැක:

PyDERASN: මම තව් සහ බ්ලොබ් සහිත ASN.1 පුස්තකාලයක් ලිවූ ආකාරය

සංදර්ශක තොරතුරු: වස්තු ඕෆ්සෙට්, ටැග් දිග, දිග දිග, අන්තර්ගත දිග, EOC තිබීම (අෂ්ටක අවසානය), BER කේතීකරණ ගුණාංගය, අවිනිශ්චිත-දිග කේතීකරණ ගුණාංගය, පැහැදිලි ටැගයේ දිග සහ ඕෆ්සෙට් (ඇත්නම්), වස්තු කූඩු ගැඹුර ව්‍යුහයන් තුළ, IMPLICIT/පැහැදිලි ටැග් අගය, යෝජනා ක්‍රමයට අනුව වස්තුවේ නම, එහි පාදම ASN.1 වර්ගය, අනුක්‍රමය/SET ඇතුළත අනුක්‍රමික අංකය, තේරීමේ අගය (ඇත්නම්), මිනිසුන්ට කියවිය හැකි නම INTEGER/ENUMERATED/BIT STRING යෝජනා ක්‍රමය, ඕනෑම පාදක වර්ගයක අගය , යෝජනා ක්‍රමයෙන් පෙරනිමි/විකල්ප ධජය, වස්තුව ස්වයංක්‍රීයව නිර්වචනය කර ඇති පරිදි විකේතනය වූ බවට ලකුණක් වන අතර මෙය සිදු වූ OID නිසා මිනිසාට කියවිය හැකි OID.

ලස්සන මුද්‍රණ පද්ධතිය විශේෂයෙන් නිර්මාණය කර ඇති අතර එමඟින් වෙනම ක්‍රම භාවිතා කරමින් දෘශ්‍යමාන කරන ලද PP වස්තු අනුපිළිවෙලක් ජනනය කරයි. තිර පිටපත සරල වර්ණ සහිත පෙළකින් විදැහුම්කරු පෙන්වයි. JSON/HTML ආකෘතියෙන් විදැහුම්කරුවන් ද ඇත, එවිට එය ASN.1 බ්‍රවුසරයේ උද්දීපනය කිරීම සමඟ දැකිය හැකිය. asn1js ව්යාපෘතිය.

වෙනත් පුස්තකාල

මෙය ඉලක්කය නොවේ, නමුත් PyDERASN සැලකිය යුතු ලෙස හැරී ගියේය ඉක්මනින් pyasn1 ට වඩා. උදාහරණයක් ලෙස, මෙගාබයිට් ප්‍රමාණයේ CRL ගොනු විකේතනය කිරීම ඔබට අතරමැදි දත්ත ගබඩා කිරීමේ ආකෘති (වේගවත්) ගැන සිතීමට සහ යෙදුම් ගෘහ නිර්මාණ ශිල්පය වෙනස් කිරීමට බොහෝ කාලයක් ගත විය හැකිය. pyasn1 CRL විකේතනය කරයි CACert.org මගේ ලැප්ටොප් පරිගණකයේ විනාඩි 20කට වඩා ගත වන අතර PyDERASN සඳහා ගත වන්නේ තත්පර 28ක් පමණි! ව්යාපෘතියක් තිබේ asn1crypto, ගුප්ත ලේඛන ව්‍යුහයන් සමඟ වේගවත් වැඩ කිරීම ඉලක්ක කර ඇත: එය තත්පර 29 කින් එකම CRL විකේතනය කරයි (සම්පූර්ණයෙන්ම, කම්මැලි නොවේ), නමුත් Python3 (983 MiB එදිරිව 498) යටතේ ධාවනය වන විට RAM මෙන් දෙගුණයක් පමණ පරිභෝජනය කරන අතර Python3.5 යටතේ 2 ගුණයකින් (1677) 488 එදිරිව), pyasn1 4.3 ගුණයකින් වැඩි (2093 එදිරිව 488) පරිභෝජනය කරයි.

මම කියපු asn1crypto අපි සළකා බැලුවේ නැහැ, මොකද ව්‍යාපෘතිය තවමත් ආරම්භක අවධියේ පවතින නිසා සහ අපි ඒ ගැන අහලා තිබුණේ නැහැ. දැන් අපි ඔහුගේ දිශාව දෙස නොබලමු, මන්ද එම සාමාන්‍යකරණය අත්තනෝමතික ස්වරූපයක් නොගන්නා බව මම වහාම සොයා ගත් අතර අනුක්‍රමිකකරණයේදී එය තත්පරයක කොටසක් නිහඬව ඉවත් කරයි. X.509 සහතික සමඟ වැඩ කිරීම සඳහා මෙය පිළිගත හැකි නමුත් සාමාන්යයෙන් එය ක්රියා නොකරනු ඇත.

මේ මොහොතේ, PyDERASN යනු මා දන්නා වඩාත්ම දැඩි නිදහස් Python/Go DER විකේතකයයි. මගේ ආදරණීය Goගේ කේතීකරණ/asn1 පුස්තකාලයේ දැඩි පරීක්ෂාවක් නොවේ OBJECT IDENTIFIER සහ UTCTime/GeneralizedTime තන්තු. සමහර විට දැඩිකම බාධාවට පත් විය හැකිය (මූලික වශයෙන් කිසිවකු විසින් නිවැරදි නොකරන පැරණි යෙදුම් සමඟ ඇති පසුගාමී අනුකූලතාවය හේතුවෙන්), එබැවින් PyDERASN සමත් විය හැක. විවිධ සැකසුම් චෙක්පත් දුර්වල කිරීම.

ව්යාපෘති කේතය හැකි තරම් සරල කිරීමට උත්සාහ කරයි. මුළු පුස්තකාලයම එක ගොනුවකි. අනවශ්‍ය කාර්ය සාධන ප්‍රශස්තකරණයන් සහ DRY කේතයකින් තොරව, අවබෝධ කර ගැනීමේ පහසුව අවධාරණය කරමින් කේතය ලියා ඇත. එය මා දැනටමත් පවසා ඇති පරිදි, UTCTime/GeneralizedTime තන්තු වල සම්පූර්ණ BER විකේතනය කිරීම සඳහා මෙන්ම, සැබෑ, සාපේක්ෂ OID, බාහිර, INSTANCE OF, EMBEDDED PDV, character STRING දත්ත වර්ග සඳහා සහය නොදක්වයි. අනෙක් සෑම අවස්ථාවකදීම, පයිතන් හි වෙනත් පුස්තකාල භාවිතා කිරීමේ කාරණය මම පුද්ගලිකව නොදකිමි.

මගේ සියලුම ව්‍යාපෘති වගේ PyGOST, GoGOST, එන්එන්සීපී, GoVPN, PyDERASN සම්පූර්ණයෙන්ම නිදහස් මෘදුකාංග, කොන්දේසි යටතේ බෙදා හරිනු ලැබේ LGPLv3+, සහ නොමිලේ බාගත කිරීම සඳහා ලබා ගත හැකිය. භාවිතයට උදාහරණ ඇත මෙහි හා ඇතුළත PyGOST පරීක්ෂණ.

සර්ජි මැට්වීව්, සයිෆර්පන්ක්, සාමාජික SPO පදනම, Python/Go සංවර්ධක, ප්‍රධාන විශේෂඥ FSUE "STC" ඇට්ලස්.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න