iOS的 security framework 框架前面已经介绍。这个框架提供有限的功能,使用它能做到的,比你想象的要少。笔者一直想找一个
iOS 下比较好的功能全面的安全算法库,结果却一无所获。不知道谁能介绍下这方面。
最终还是只有求助于闻名已久的Openssl library。
Openssl 确实十分强大,然而其糟糕文档仍让人难以满意。当然,网络上使用Openssl 的例子非常多,不过能写这个的似乎都是高手,必然跟菜鸟划清界限——如果你是一个菜鸟,高手是不会跟你解释每行代码分别都是什么意思。坚信求人不如求己,钻研了许久,终于写出了点能够运行的
Code。
主要参考的来源:一是Openssl 库中的源代码,一是这本书《Openssl编程》(赵春平
著)——说它是书可能有些勉强,因为没有得以出版(不知道出版社的编辑们看到这本书没?)。但它确实是本 Openssl 方面比较全面的介绍(难得的中文参考书),如果你想对
Openssl 有所了解,不妨把它找来看看(openssl.cn 论坛上)。
一、编译iOS Openssl 静态库
请参考《在你的iOS App 中使用 OpenSSL 库》。
二、在Xcode 项目中进行设置
同上
三、使用Openssl 验证
直接上代码:
#import
#import
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