您的位置:首页 > 运维架构

使用 Openssl 验证自签名证书

2011-06-15 14:11 756 查看
iOS的 security framework 框架前面已经介绍。这个框架提供有限的功能,使用它能做到的,比你想象的要少。笔者一直想找一个
iOS 下比较好的功能全面的安全算法库,结果却一无所获。不知道谁能介绍下这方面。

最终还是只有求助于闻名已久的 Openssl library。

Openssl 确实十分强大,然而其糟糕文档仍让人难以满意。当然,网络上使用Openssl 的例子非常多,不过能写这个的似乎都是高手,必然跟菜鸟划清界限——如果你是一个菜鸟,高手是不会跟你解释每行代码分别都是什么意思。坚信求人不如求己,钻研了许久,终于写出了点能够运行的
Code。

主要参考的来源:一是 Openssl 库中的源代码,一是这本书《Openssl编程》(赵春平
著)——说它是书可能有些勉强,因为没有得以出版(不知道出版社的编辑们看到这本书没?)。但它确实是本 Openssl 方面比较全面的介绍(难得的中文参考书),如果你想对
Openssl 有所了解,不妨把它找来看看(openssl.cn 论坛上)。

一、编译 iOS Openssl 静态库

请参考《在你的 iOS App 中使用 OpenSSL 库》。

二、在 Xcode 项目中进行设置

同上

三、使用 Openssl 验证

直接上代码:

#import
<OpenSsl/x509.h>

#import
<Openssl/x509v3.h>

void
loadCert(
NSString
*,
X509
*);

void
printX509(
X509
*);

void
verity(
X509
*,
NSString
*);

int
main(
int
argc,
char
*argv[]) {

NSAutoreleasePool
* pool = [[
NSAutoreleasePool

alloc
]
init
];

NSString
*file=
@"/Users/username/Desktop/client.cer"
;

//
新建一个
x509
结构

X509
*x=
X509_new
();

loadCert
(file,x);

printX509
(x);

//
开始验证

verity
(x,file);

//
释放结构体

X509_free
(x);

[pool
release
];

return

0
;

}

//
加载证书到
X509
结构

void
loadCert(
NSString
* string,
X509
* x){

NSData
* certData;

unsigned

char
buf[
4096
],*p;

int
len;

assert
(string!=
nil
);

//
读取证书文件

certData=[
NSData

dataWithContentsOfFile
:string];

assert
(certData!=
nil
);

len=certData.
length
;

// NSData-->uchar*

[certData
getBytes
:(
void
*)buf
length
:len];

// p-->buf[0]

p=buf;

//

buf
中的数据进行解码,并返回一个
X509
结构

d2i_X509
(&x,(
const

unsigned

char

**)&p,len);

}

//
打印
X509
结构

void
printX509(
X509
* x){

int
ret;

BIO

*b;

//
初始化一个文件
BIO

b=
BIO_new
(
BIO_s_file
());

//
把标准输出
stdout
指向这个文件
BIO

BIO_set_fp
(b,
stdout
,
BIO_NOCLOSE
);

//

X509
结构打印输出到文件
BIO

ret=
X509_print
(b,x);

//
释放流

BIO_free
(b);

}

//
验证自签名证书

void
verity(
X509
* x1,
NSString
* string){

int
i=
0
;

X509_LOOKUP
*lookup=
NULL
;

//
证书
store
结构体

X509_STORE
*cert_ctx;

//
证书
store
相关的上下文

X509_STORE_CTX
*csc;

//
构造
CA

X509_STORE
结构体,包含所有有效证书链和废止证书链,用于校验

cert_ctx=
X509_STORE_new
();

//

store
中加入一个搜索,可以查找单个的文件

lookup=
X509_STORE_add_lookup
(cert_ctx,
X509_LOOKUP_file
());

assert
(lookup!=
NULL
);

//
通过
lookup
加载
client.cer
内的证书(自签名)

i=
X509_LOOKUP_load_file
(lookup,[string

UTF8String
],
X509_FILETYPE_ASN1
);

assert
(i!=
0
);

//

flags
赋值给
ctx
里面的
flags,
表明了验证证书时需要验证哪些项

// flags
可以是:

//
X509_V_FLAG_IGNORE_CRITICAL


//
X509_V_FLAG_CB_ISSUER_CHECK


// X509_V_FLAG_CRL_CHECK


//
X509_V_FLAG_CRL_CHECK│X509_V_FLAG_CRL_CHECK_ALL


X509_STORE_set_flags
(cert_ctx,
X509_V_FLAG_CRL_CHECK_ALL
);

csc =
X509_STORE_CTX_new
();

if
(!
X509_STORE_CTX_init
(csc,cert_ctx
,x1,
NULL
))

{

NSLog
(
@"Can
NOT ctx init"
);

return
;

}

//
开始校验

i=
0
;

i=
X509_verify_cert
(csc);

X509_STORE_CTX_free
(csc);

if
(i)

NSLog
(
@"cert
OK"
);

else

{

NSLog
(
@"cert
error"
);

}

}

先搞个有效证书,client.cer,放在你的桌面上。运行程序,控制台打印:

cert OK

如果证书失效了(比如把证书有效期改为无效),控制台则打印:

cert error
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: