一:在证书中加入中文信息,其实也就是一个GB2312转化为UTF8的过程
openssl命令行工具是无法显示中文证书的,需要更改一下原代码,下面以cisoca为例:
int AddSubjectEntry(X509_NAME *pSubjectName,char *key, char *value)
{
int nid,iCount=0,iLen;
X509_NAME_ENTRY *ent;
ASN1_STRING stmp, *str = &stmp;
ASN1_STRING stmp1, *str1 = &stmp1;
char cbuf[1024];
char *p=cbuf;
wchar_t wc;
unsigned int i
wchar_t * ws =new unsigned short[sizeof(wchar_t) * (100)];
(void)setlocale(LC_ALL, "");
if (mbstowcs(ws,value,100) == -1)
{
sprintf(szErrorString,"mbstowcs convert error");
delete ws;
return false;
}
iLen=wcslen(ws)*2;
for(i=0;i {
wc=ws[i];
*p++=wc/256;
*p++=wc%256;
}
ASN1_mbstring_copy(&str,(const unsigned char*),cbuf,iLen,MBSTRING_BMP,B_ASN1_UTF8STRING);
if( (nid =OBJ_txt2nid(key)) == NID_undef )
{
sprintf(szErrorString,"Can not find NID:%s",key);
return false;
}
ent = X509_NAME_ENTRY_create_by_NID(NULL,nid,V_ASN1_UTF8STRING,stmp.data,stmp.length);
if(ent == NULL)
{
sprintf(szErrorString,"Error on creat %s name entry!",key);
return false;
}
if(X509_NAME_add_entry(pSubjectName,ent,-1,0) != 1)
{
sprintf(szErrorString,"Error on add %s name entry!",key);
return false;
}
delete ws;
return true;
}
二:在openssl中将UTF8转换为GB2312
UTF_GB(char *utf,char *gb)
{
setlocale(LC_CTYPE, "");
ASN1_STRING *asn1_str=ASN1_STRING_new();
ASN1_STRING_set(asn1_str, (const void *)utf, strlen(utf));
asn1_str->type=12;
BIO *mem = BIO_new(BIO_s_mem());
BIO_set_close(mem, BIO_CLOSE);
ASN1_STRING_print_ex(mem,asn1_str,ASN1_STRFLGS_ESC_QUOTE );
BUF_MEM *bptr;
BIO_get_mem_ptr(mem, &bptr);
int len=bptr->length;
char * pbuf=new char[len+1];
memset(pbuf,0,len+1);
memcpy(pbuf,bptr->data,len);
UINT uChina[255]={0};
char cEnglish[64][128]={0};
char pmbbuf[3]={0};
char * pdest=NULL;
UINT uUlocal=0;
char * ptemp=pbuf;
for(UINT j=0;;j++)
{
pdest=strstr(ptemp,"//U");
if(pdest == NULL)
{
strncpy(cEnglish[j],ptemp,strlen(ptemp));
break;
}
uUlocal = pdest - ptemp + 1;
strncpy(cEnglish[j],ptemp,uUlocal-1);
char hex[5]={0};
strncpy(hex,ptemp+uUlocal+1,4);
int ten=HexToTen(hex);
uChina[j]=ten;
ptemp=ptemp+uUlocal+5;
}
if (mem != NULL) BIO_free(mem);
wchar_t pwchello[2]={0};
for(UINT k=0;k<=j;k++)
{
if(k>63)break;
strcat(gb,cEnglish[k]);
pwchello[0]=uChina[k];
int result = wcstombs( pmbbuf, pwchello, 2 );
if(result!=-1)strncat(gb,pmbbuf,2);
}
delete [] pbuf;
}
int HexToTen(const char * pHex)
{
DWORD dwHexNum=0;
for (; *pHex!=0 ; pHex++)
{
dwHexNum *= 16;
if ((*pHex>='0') && (*pHex<='9'))
dwHexNum += *pHex-'0';
else if ((*pHex>='a') && (*pHex<='f'))
dwHexNum += *pHex-'a'+10;
else if ((*pHex>='A') && (*pHex<='F'))
dwHexNum += *pHex-'A'+10;
else
-1;
}
return dwHexNum;
}
例如:
X509_NAME_get_text_by_NID(X509_get_subject_name (m_pCert),NID_countryName,m_country,256);
UTF_GB(m_country,gb);
printf(gb);输出就是正确的汉字。
讨论的网址http://www.infosecurity.org.cn/forum/read.php?fid=11&tid=185&fpage=1