
ASN.1 परिवहन वाक्यविन्यास एक नेटवर्क पर संचरण के लिए बाइट्स के अनुक्रम में मान्य प्रकारों के चर के मूल्यों को परिवर्तित करने का एक अनूठा तरीका परिभाषित करता है। ASN.1 में, इसे बेसिक एन्कोडिंग नियम (BER) कहा जाता है। नियम पुनरावर्ती हैं, इसलिए कंपोजिट ऑब्जेक्ट्स को एन्कोडिंग घटक ऑब्जेक्ट्स के एन्कोडेड अनुक्रमों की एक चेनिंग है। ASN.1 प्रोटोकॉल एक
सरल और समझने योग्य भाषा में डेटा संरचना का वर्णन करता है।
प्रत्येक संचरित मूल्य - दोनों मूल और व्युत्पन्न प्रकार - तीन क्षेत्रों के होते हैं:
- आईडी;
- डेटा फ़ील्ड लंबाई (बाइट्स में);
- डेटा फ़ील्ड।
यदि आप हमेशा डेटा फ़ील्ड की लंबाई निर्दिष्ट करते हैं (मैं इसे एक अच्छा अभ्यास मानता हूं), तो डेटा फ़ील्ड के अंत का ध्वज उपयोग नहीं किया जाता है।
ASN.1 के लिए कई अलग-अलग संकलक हैं, जो विभिन्न प्रोग्रामिंग भाषाओं के लिए भुगतान और मुफ्त दोनों हैं, लेकिन हम हाथ में बहुत सरल कुछ करना चाहेंगे।
सॉफ्टवेयर डेवलपर्स के विशाल बहुमत
ASN.1 मानक
परिसर पाते हैं। मैंने भी हाल तक ऐसा ही सोचा था। पीकेआई / पीकेआई / क्रिप्टोग्राफी के क्षेत्र में काम करना लगभग हर दिन आप एक्स 509 प्रमाण पत्र, प्रमाणपत्र अनुरोध, निरस्त प्रमाण पत्रों की सूची के रूप में एएसएन 1 संरचनाओं से निपटते हैं। और सूची बनती जाती है। और इसलिए, PKCS # 11 टोकन / स्मार्टकार्ड पर एक प्रमुख जोड़ी बनाने के साथ PKCS # 10 प्रारूप में एक प्रमाण पत्र अनुरोध बनाने के लिए एक उपयोगिता पर काम करते हुए, मुझे स्वाभाविक रूप से, विशेष रूप से, प्रमाणपत्र अनुरोध के लिए इसे लिखने के लिए सार्वजनिक कुंजी का asn1 संरचना तैयार करना पड़ा। :
C-Sequence C-Sequence (<>) Object Identifier (<>) <oid public key> C-Sequence (<>) Object Identifier (<>) <oid > Object Identifier (<>) <oid > Bit String (<>) < >
चूंकि हमने क्रिप्टोग्राफिक सूचना सुरक्षा उपकरण के रूप में रूसी क्रिप्टोग्राफी के समर्थन के साथ PKCS # 11 टोकन का उपयोग किया था, इसलिए इस संरचना के लिए स्रोत सामग्री टोकन से निम्नलिखित टेम्पलेट के अनुसार प्राप्त की गई थी:
CK_BYTE gostr3410par[12]; CK_BYTE gostr3411par[12]; CK_ULONG gostr3410par_len; CK_ULONG gostr3411par_len; CK_BYTE pubkey[128]; CK_ULONG pubkeu_len; CK_KEY_TYPE key_type; CK_ATTRIBUTE templ_pk[] = { . . . {CKA_GOSTR3410PARAMS, gostr3410par, sizeof(gostr3410par)}, {CKA_GOSTR3411PARAMS, gostr3411par, sizeof(gostr3410par)}, {CKA_VALUE, pubkey, sizeof(pubkey)}, {CKA_KEY_TYPE, &key_type, sizeof(key_type)} }
इस संरचना से सीधे, CKA_VALUE विशेषता के मान जिनमें सार्वजनिक कुंजी मान है और CKA_GOSTR3410PARAMS और CKA_GOSTR3411PARAMS विशेषताएँ हैं जिनमें हस्ताक्षर पैरामीटर और oh1-publickeyinfo को भरने के लिए हैश पैरामीटर का उपयोग किया जाएगा।
विशेषता CKA_KEY_TYPE, जो CKK_GOSTR3410 और CKK_GOSTR3410_512 मानों को ले सकती है (उन परिस्थितियों में जब GOST R 34.10-2001 हस्ताक्षर एल्गोरिथ्म काम करना जारी रखता है: अस्पष्ट रूप से प्रमुख जोड़ी एल्गोरिदम को परिभाषित करता है। यदि CKA_KEY_TYPE विशेषता का मान CKK_GOSTR3410_512 के बराबर है, तो, निश्चित रूप से, यह GOST R 34.10-2012 की कुल लंबाई 512 बिट्स के साथ एल्गोरिदम को इंगित करता है (oid = 1.2.643.7.1.1.1.2)। लेकिन अगर यह केवल CKK_GOSTR3410 के बराबर है, तो इस बारे में अस्पष्टता है कि यह कुंजी किस प्रकार की है: GOST R 34.10-2001 या फिर भी यह 256 बिट्स की कुंजी लंबाई के साथ GOST R 34.10-2012 है। CKA_GOSTR3411PARAMS विशेषता इस अस्पष्टता को हल करने में मदद करती है।
उदाहरण के लिए, हम ध्यान दें कि पैरामीटर TKA-26 की सिफारिशों के अनुसार टोकन पर CKA_GOSTR3410PARAMS और CKA_GOSTR3411PARAMS पैरामीटर उदाहरण के लिए, उदाहरण के लिए इनकोड किए गए ऑब्जेक्ट पहचानकर्ता के रूप में संग्रहीत हैं:
\ x06 \ x06 \ x2a \ x85 \ x03 \ x02 \ x02 \ x13, जहां शून्य बाइट अनुक्रम का प्रकार निर्धारित करता है (0x06 ऑब्जेक्ट पहचानकर्ता है, नीचे दी गई तालिका देखें। दूसरा बाइट लंबाई इंगित करता है (सामान्य स्थिति में, लंबाई कई बाइट्स ले सकती है) लेकिन उस पर और नीचे) डेटा क्षेत्र जिसमें ओड बाइनरी रूप में संग्रहीत है।
यदि इस पैरामीटर में GOST R 34.10-2012 हैश एल्गोरिथ्म की लंबाई 256 बिट्स (oid = 1.2.643.7.1.1.2.2) है, तो द्विआधारी रूप में "\ x2a \ x 85 \ x 03 \ x 07 x 07 x 01 \ x 01 \ x" 02 \ x02 "), तो कुंजी प्रकार को 256 बिट्स की लंबाई के साथ GOST R 34.10-2012 के रूप में सेट किया जाना चाहिए। अन्यथा, यह GOST R 34.10-2001 की कुंजी है। कुंजी के प्रकार का निर्धारण करने के लिए एल्गोरिथ्म इस तरह दिख सकता है:
. . . for (curr_attr_idx = 0; curr_attr_idx < (sizeof(templ_pk)/sizeof(templ_pk[0])); curr_attr_idx++){ curr_attr = &templ_pk[curr_attr_idx]; if (!curr_attr->pValue) { continue; } swith (curr_attr->type) { . . . case CKA_VALUE: pubkey_len = curr_attr->ulValueLen; break; case CKA_GOSTR3410PARAMS: gostr3410par_len = curr_attr->ulValueLen; break; case CKA_GOSTR3410PARAMS: gostr3411par_len = curr_attr->ulValueLen; break; case CKA_KEY_TYPE: ulattr = curr_attr->pValue; if (*ulattr == CKK_GOSTR3410) { if (!memmem(gostr3411par), gostr3411par_len,"\x06\x08\x2a\x85\x03\x07", 6)) { strcpy(oid_key_type, "1.2.643.2.2.19"); memcpy(oid_key_type_asn1("\x06\x06\x2a\x85\x03\x02\x02\x13", 8); } else { strcpy(oid_key_type, ("1 2 643 7 1 1 1 1"); memcpy(oid_key_type_asn1 ("\x06\x08\x2a\x85\x03\x07\x01\x01\x01\x01", 10); } } else if (*ulattr == CKK_GOSTR3410_512) { strcpy(oid_key_type, ("1 2 643 7 1 1 1 2"); memcpy(oid_key_type_asn1 ("\x06\x08\x2a\x85\x03\x07\x01\x01\x01\x02", 10); } else { fprintf(stderr, "tclpkcs11_perform_pki_keypair CKK_GOSTR ERROR\n"); return (-1) } break; . . . } } . . .
अब हमारे पास asn1 सार्वजनिक कुंजी संरचना बनाने के लिए सभी स्रोत डेटा हैं।
स्मरण करें कि asn1-संरचना के प्रत्येक तत्व में तीन फ़ील्ड शामिल हैं:
- आईडी;
- डेटा फ़ील्ड लंबाई (बाइट्स में);
- डेटा फ़ील्ड।
यहाँ PKI / PKI में प्रयुक्त कुछ प्रकार के पहचानकर्ताओं के लिए
एक कोडिंग
तालिका दी गई है:
नाम टाइप करें | संक्षिप्त विवरण | डीईआर एन्कोडिंग में टाइप प्रतिनिधित्व |
---|
SEQUENCE | विभिन्न प्रकारों से मिलकर डेटा संरचना का वर्णन करने के लिए उपयोग किया जाता है। | 30 |
पूर्णांक | पूर्णांक। | 02 |
उद्देश्य पहचान | पूर्णांकों का एक क्रम। | 06 |
UTCTime | अस्थायी प्रकार, वर्ष का निर्धारण करने के लिए 2 अंक होते हैं | 17 |
GeneralizedTime | विस्तारित समय प्रकार, वर्ष को इंगित करने के लिए 4 अंक होते हैं। | 18 |
सेट | विभिन्न प्रकारों की डेटा संरचना का वर्णन करता है। | 31 |
UTF8String | स्ट्रिंग डेटा का वर्णन करता है। | 0C |
शून्य | वास्तव में NULL | 05 |
BIT STRING | बिट्स के एक क्रम को संग्रहीत करने के लिए टाइप करें। | 03 |
OCTET STRING | बाइट्स के एक क्रम को संग्रहीत करने के लिए टाइप करें | 04 |
जब asn1- संरचनाओं के साथ काम करते हैं, तो uninitiated के लिए सबसे बड़ा झटका डेटा फ़ील्ड की लंबाई एन्कोडिंग की विधि के कारण होता है, खासकर जब इसे बनाते हैं, और यदि आप कंप्यूटर आर्किटेक्चर (Littleendien, bigendien) को ध्यान में रखते हैं। यह एक संपूर्ण
विज्ञान है । और इसलिए, इस क्षेत्र को बनाने के लिए एल्गोरिथ्म पर चर्चा करने की प्रक्रिया में, स्प्रिंटफ फ़ंक्शन का उपयोग करने के लिए विचार आया, जो खुद वास्तुकला को ध्यान में रखेगा, और लंबाई को संग्रहीत करने के लिए बाइट्स की संख्या फ़ंक्शन कोड द्वारा देखी जा सकती है, जो डेटा प्रकार पहचानकर्ता और डेटा लंबाई के साथ एक बफर तैयार करती है:
unsigned char *wrap_id_with_length(unsigned char type,
फ़ंक्शन डेटा की लंबाई को ध्यान में रखते हुए, एक asn1 संरचना के साथ एक बफर को एक संकेतक लौटाता है। यह हेडर की लंबाई से ऑफसेट के साथ प्राप्त बफर में इस डेटा को कॉपी करने के लिए रहता है। हेडर की लंबाई को लीनसन पैरामीटर के माध्यम से लौटाया जाता है।
यह कैसे काम करता है यह जाँचने के लिए, हम एक साधारण उपयोगिता लिखेंगे:
#include <stdio.h> #include <stdlib.h> #define digitp(p) (*(p) >= '0' && *(p) <= '9') #define hexdigitp(a) (digitp (a) \ || (*(a) >= 'A' && *(a) <= 'F') \ || (*(a) >= 'a' && *(a) <= 'f')) #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) int main (int argc, char *argv[]) { unsigned char *hdrasn; unsigned char type; unsigned long length; unsigned long lenasn; if (argc != 3) { fprintf (stderr, "Usage: wrap_id_with_length <id> <length>\n"); exit(-1); } type = atoi(argv[1]); length = atol(argv[2]); fprintf (stderr, "<id=%02x> <length=%lu>\n", type, length); if (length == 0) { fprintf (stderr, "Bad length=%s\nUsage: wrap_id_with_length <id> <length>\n", argv[2]); exit(-1); } hdrasn = wrap_id_with_length(type, length, &lenasn); fprintf (stderr, "Length asn1-buffer=%lu, LEN_HEADER=%lu, LEN_DATA=%lu\n", lenasn, lenasn - length, length); }
इसे wra_id_with_length फ़ंक्शन के साथ wra_id_with_length.c फ़ाइल में सहेजें।
हम प्रसारण:
$cc –o wrap_id_with_length wrap_id_with_length.c $
विभिन्न स्रोत डेटा के साथ परिणामी प्रोग्राम चलाएं। डेटा प्रकार एक दशमलव संख्या द्वारा निर्दिष्ट किया गया है:
bash-4.3$ ./wrap_id_with_length 06 8 <id=06> <length=8> ASN1 - :0608 Length asn1-buffer=10, LEN_HEADER=2, LEN_DATA=8 bash-4.3$ ./wrap_id_with_length 06 127 <id=06> <length=127> ASN1 - :067f Length asn1-buffer=129, LEN_HEADER=2, LEN_DATA=127 bash-4.3$ ./wrap_id_with_length 48 128 <id=30> <length=128> ASN1 - :308180 Length asn1-buffer=131, LEN_HEADER=3, LEN_DATA=128 bash-4.3$ ./wrap_id_with_length 48 4097 <id=30> <length=4097> ASN1 - :30821001 Length asn1-buffer=4101, LEN_HEADER=4, LEN_DATA=4097 bash-4.3$
आप किसी भी कैलकुलेटर का उपयोग करके हेडर के गठन की शुद्धता की जांच कर सकते हैं:

हम किसी भी ASN1- संरचना के लिए तैयार हैं। लेकिन सबसे पहले, wra_id_with_length फ़ंक्शन में छोटे बदलाव करें और इसे कॉल करें
wrap_for_asn1: unsigned char *wrap_for_asn1(unsigned char type, unsigned char *prefix, unsigned long prefix_len, unsigned char *wrap, unsigned long wrap_len, unsigned long *lenasn){ unsigned long length; int buflen = 0; unsigned char *buf; char *format; const char buf_for_len[100]; const char *s; char f0[] = "%02x%02x"; char f1[] = "%02x81%02x"; char f2[] = "%02x82%04x"; char f3[] = "%02x83%06x"; char f4[] = "%02x84%08x"; length = prefix_len + wrap_len; buflen += ( length <= 0x80 ? 1: length <= 0xff ? 2: length <= 0xffff ? 3: length <= 0xffffff ? 4: 5); buf = malloc(length + buflen); switch (buflen - 1) { case 0: format = f0; break; case 1: format = f1; break; case 2: format = f2; break; case 3: format = f3; break; case 4: format = f4; break; }
जैसा कि आप देख सकते हैं, परिवर्तन न्यूनतम हैं। इनपुट मापदंडों के रूप में, डेटा स्वयं जोड़ा जाता है, जो फ़ंक्शन के अंदर एक asn1- संरचना में पैक किया जाता है। इसके अलावा, दो बफ़र्स को एक ही बार में इनपुट पर फीड किया जा सकता है। यह हमें सुविधाजनक लगता है।
टेस्ट केस पेश करने से पहले, हम तीन और कार्यों के कोड देते हैं। पहला
oid2buffer फंक्शन बिंदीदार दशमलव फॉर्म से DER एन्कोडिंग में कनवर्ट करता है। हमें इस फ़ंक्शन को बदलने की आवश्यकता है, विशेष रूप से, कुंजी जोड़ी की oids (ऊपर देखें)।
समारोह पाठ यहाँ है:स्टेटिक चार * oid2buffer (चार * oid_str, अहस्ताक्षरित लंबी * लेन) {
char * curstr;
char * curstr1;
चार * अगला;
अहस्ताक्षरित int firstval;
अहस्ताक्षरित int secondval;
अहस्ताक्षरित int val;
अहस्ताक्षरित चार बफ़ [5];
इंट काउंट;
अहस्ताक्षरित चार oid_hex [100];
char * res;
int i;
अगर (oid_str == NULL) {
* लेन = 0;
वापसी NULL;
}
* लेन = 0;
curstr = strdup ((const char *) oid_str);
curstr1 = curstr;
nextstr = strchr (curstr, '' ');
यदि (अगला == पूरा) {
* लेन = 0;
वापसी NULL;
}
* अगली भुजा = '\ 0';
firstval = atoi (curstr);
curstr = nextstr + 1;
nextstr = strchr (curstr, '' ');
अगर (अगला) {
* अगली भुजा = '\ 0';
}
secondval = atoi (curstr);
अगर (पहले> 2) {
* लेन = 0;
वापसी NULL;
}
अगर (दूसरा> 39) {
* लेन = 0;
वापसी NULL;
}
oid_hex [0] = (अहस्ताक्षरित चार) ((पहले * 40) + दूसरा);
i = 1;
जबकि (अगला) {
curstr = nextstr + 1;
nextstr = strchr (curstr, '' ');
अगर (अगला) {
* अगली भुजा = '\ 0';
}
मेमसेट (buf, 0, sizeof (buf));
वैल = अटोई (कर्स्ट);
गिनती = 0;
अगर (curstr [0]! = '0')
जबकि (वैल) {
buf [गिनती] = (val & 0x7f);
वैल = वैल >> 7;
गिनती ++;
}
और {
buf [गिनती] = (val & 0x7f);
वैल = वैल >> 7;
गिनती ++;
}
जबकि (गिनती--) {
अगर (गिनती) {
oid_hex [i] = buf [गिनती] | 0x80;
} {
oid_hex [i] = buf [गिनती];
}
मैं ++;
}
}
res = (char *) malloc (i);
अगर (रेस) {
memcpy (रेस, oid_hex, i);
* लेन = मैं;
}
free (curstr1);
वापसी Res;
}
अन्य दो कार्य बाइनरी बफर को हेक्साडेसिमल काउंट (बफर 2 हेक्स) और इसके विपरीत (हेक्स 2 बफ़र) में परिवर्तित करने की अनुमति देते हैं।
ये कार्य यहाँ हैं:स्थिर चार *
बफर 2 हेक्स (const अहस्ताक्षरित चार * src, size_t len)
{
int i;
चार * भाग्य;
char * res;
dest = (char *) malloc (len * 2 + 1);
res = dest;
अगर (भाग्य)
{
के लिए (i = 0; मैं <लेन; मैं ++, भाग्य + = 2)
स्प्रिंटफ (भाग्य, "% 02X", src [i]);
}
वापसी Res;
}
स्थिर शून्य *
hex2buffer (const char * string, size_t * r_length)
{
const char * s;
अहस्ताक्षरित चार * बफर;
size_t लंबाई;
बफर = मॉलोक (स्ट्रलेन (स्ट्रिंग) / 2 + 1);
लंबाई = 0;
के लिए (s = string; * s; s + = 2)
{
अगर (hexdigitp (s) ||!! hexdigitp (s + 1)) {
fprintf (stderr, "अमान्य हेक्स अंक \"% s \ "\ n", स्ट्रिंग) में;
}
((अहस्ताक्षरित चार *) बफर) [लंबाई ++] = xtoi_2 (s);
}
* r_length = लंबाई;
बफर वापस;
}
ये कार्य डिबगिंग के लिए बहुत सुविधाजनक हैं, और सबसे अधिक संभावना है कि उनमें से कई हैं।
और अब हम सार्वजनिक कुंजी के asn1- संरचना को प्राप्त करते हुए कार्य के समाधान पर लौटते हैं। हम एक उपयोगिता लिखेंगे जो ASN1_PIBINFO.der में सार्वजनिक कुंजी के asn1- संरचना को उत्पन्न और बचाएगा।
यह उपयोगिता यहां स्थित है: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdint.h> #include <string.h> #define digitp(p) (*(p) >= '0' && *(p) <= '9') #define hexdigitp(a) (digitp (a) \ || (*(a) >= 'A' && *(a) <= 'F') \ || (*(a) >= 'a' && *(a) <= 'f')) #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) /* oid2buffer*/ /* buffer2hex hex2buffer*/ /* wrap_for_asn1*/ int main() { int fd; unsigned char *asn, *asn1, *asn2, *asn3, *pubkeyalgo; unsigned char* pubkey_bin; // char gost3410par[] = "\x06\x7\x2a\x85\x03\x02\x02\x23\x01"; unsigned long gost3410par_len = sizeof(gost3410par) - 1; char gost3411par[] = "\x06\x8\x2a\x85\x03\x07\x01\x01\x02\x02"; unsigned long gost3411par_len = sizeof(gost3411par) - 1; unsigned char pubkey_hex[] = "9af03570ed0c54cd4953f11ab19e551022cd48603326c1b9b630b1cff74e5a160ba1718166cc22bf70f82bdc957d924c501b9332491cb3a36ce45770f05487b5"; char pubkey_oid_2001[] = "1.2.643.2.2.19"; char pubkey_oid_2012_256[] = "1.2.643.7.1.1.1.1"; char pubkey_oid_2012_512[] = "1.2.643.7.1.1.1.2"; unsigned long pubkey_len, pubkey_len_full, len10, len11, len12, lenalgo; unsigned char *pkalgo; unsigned long pkalgo_len; uint16_t x = 1; /* 0x0001 */ printf("%s\n", *((uint8_t *) &x) == 0 ? "big-endian" : "little-endian"); ////pubkeyinfo // if (!memmem(gost3411par, 8, "\x2a\x85\x03\x07", 4)) { // 34.11-94, 34.10-2001 - 1.2.643.2.2.19 pubkeyalgo = (unsigned char *)oid2buffer(pubkey_oid_2001, &lenalgo); } else if (!memcmp(gost3411par, "\x2a\x85\x03\x07\x01\x01\x02\x02", 8)){ // 34.11-2012-256, 34.10-2012-256 - 1.2.643.7.1.1.1.1 pubkeyalgo = (unsigned char *)oid2buffer(pubkey_oid_2012_256, &lenalgo); } else { // 34.11-2012-512, 34.10-2012-512 - 1.2.643.7.1.1.1.2 pubkeyalgo = (unsigned char *)oid2buffer(pubkey_oid_2012_512, &lenalgo); } pubkey_bin =(unsigned char*)hex2buffer((const char *)pubkey_hex, &pubkey_len); // asn1 = wrap_for_asn1_bin('\x04', (unsigned char *)"", 0, pubkey_bin, pubkey_len, &pubkey_len); asn = wrap_for_asn1_bin('\x03', (unsigned char *)"\x00", 1, asn1, pubkey_len, &pubkey_len_full); fprintf(stderr, "PUBLIC_VALUE=%s\n", buffer2hex(asn, pubkey_len_full)); free(asn1); // asn3 = wrap_for_asn1_bin('\x30', (unsigned char*)gost3410par, gost3410par_len, (unsigned char *)gost3411par, gost3411par_len, &len12); fprintf(stderr, "\nPARAMS len12=%lu, FULL=%s\n", len12, buffer2hex(asn3, len12)); // pkalgo = wrap_for_asn1_bin('\x06', (unsigned char *)"", 0, pubkeyalgo, lenalgo, &pkalgo_len); // asn2 = wrap_for_asn1_bin('\x30', pkalgo, pkalgo_len, asn3, len12, &len11); fprintf(stderr, "PubKEY=%s\n", buffer2hex(asn3, len11)); asn1 = wrap_for_asn1_bin('\x30', asn2, len11, asn, pubkey_len_full, &len10); free(asn2); free(asn3); fprintf(stderr, "\n%s\n", buffer2hex(asn1, len10)); fd = open ("ASN1_PUBINFO.der", O_TRUNC|O_RDWR|O_CREAT,S_IRWXO); write(fd, asn1, len10); close(fd); free(asn1); chmod("ASN1_PUBINFO.der", 0666); }
परिणाम को सत्यापित करने के लिए, हम एनएसएस पैकेज से व्युत्पन्न और पीपी उपयोगिताओं का उपयोग करेंगे।
पहली उपयोगिता हमें सार्वजनिक कुंजी के asn1 संरचना को दिखाएगी:
$ derdump -i ASN1_PUBINFO.der C-Sequence (102) C-Sequence (31) Object Identifier (8) 1 2 643 7 1 1 1 2 (GOST R 34.10-2012 Key 512) C-Sequence (19) Object Identifier (7) 1 2 643 2 2 35 1 Object Identifier (8) 1 2 643 7 1 1 2 2 (GOST R 34.11-2012 256) Bit String (67) 00 04 40 9a f0 35 70 ed 0c 54 cd 49 53 f1 1a b1 9e 55 10 22 cd 48 60 33 26 c1 b9 b6 30 b1 cf f7 4e 5a 16 0b a1 71 81 66 cc 22 bf 70 f8 2b dc 95 7d 92 4c 50 1b 93 32 49 1c b3 a3 6c e4 57 70 f0 54 87 b5 $
दूसरा कुंजी की सामग्री दिखाएगा:
$ pp -t pk -i ASN1_PUBINFO.der Public Key: Subject Public Key Info: Public Key Algorithm: GOST R 34.10-2012 512 Public Key: PublicValue: 9a:f0:35:70:ed:0c:54:cd:49:53:f1:1a:b1:9e:55:10: 22:cd:48:60:33:26:c1:b9:b6:30:b1:cf:f7:4e:5a:16: 0b:a1:71:81:66:cc:22:bf:70:f8:2b:dc:95:7d:92:4c: 50:1b:93:32:49:1c:b3:a3:6c:e4:57:70:f0:54:87:b5 GOSTR3410Params: OID.1.2.643.2.2.35.1 GOSTR3411Params: GOST R 34.11-2012 256 $
जो लोग चाहते हैं, उदाहरण के लिए, ओपनसीएल उपयोगिता के साथ दो-चेक कर सकते हैं, अधिमानतः एक
जुड़े GOST इंजन के साथ:
$ /usr/local/lirssl_csp_64/bin/lirssl_static asn1parse -inform DER -in ASN1_PUBINFO.der 0:d=0 hl=2 l= 102 cons: SEQUENCE 2:d=1 hl=2 l= 31 cons: SEQUENCE 4:d=2 hl=2 l= 8 prim: OBJECT :GOST R 34.10-2012 with 512 bit modulus 14:d=2 hl=2 l= 19 cons: SEQUENCE 16:d=3 hl=2 l= 7 prim: OBJECT :id-GostR3410-2001-CryptoPro-A-ParamSet 25:d=3 hl=2 l= 8 prim: OBJECT :GOST R 34.11-2012 with 256 bit hash 35:d=1 hl=2 l= 67 prim: BIT STRING $
जैसा कि आप देख सकते हैं, परिणामस्वरूप ASN1 संरचना को हर जगह सफलतापूर्वक परीक्षण किया गया है।
Asn1 संरचनाओं के गठन के लिए प्रस्तावित एल्गोरिथ्म और उपयोगिता को किसी भी ASN1 संकलक और विस्तार पुस्तकालयों (एक ही ओपनसेल) के उपयोग की आवश्यकता नहीं है और उपयोग करने के लिए बहुत सुविधाजनक निकला। हम उन्हें अगले लेख में याद करेंगे, जब
पास की इच्छा पूरी हो जाएगी और एक ग्राफिकल उपयोगिता प्रस्तुत की जाएगी, जो न केवल "प्रमाण पत्र जारी" करती है और उनकी वैधता की पुष्टि करती है, बल्कि पीकेसीएस # 11 टोकन पर एक प्रमुख जोड़ी भी उत्पन्न करती है, और एक योग्य प्रमाण पत्र के लिए अनुरोध करती है। इस अनुरोध के साथ, आप सुरक्षित रूप से एक प्रमाण पत्र के लिए सीए जा सकते हैं। सवालों के आगे, मैं तुरंत ध्यान देता हूं कि बाद के मामले में, टोकन को रूस के एफएसबी के प्रमाणीकरण प्रणाली में एक क्रिप्टोग्राफिक सूचना सुरक्षा प्रणाली के रूप में प्रमाणित किया जाना चाहिए।