WinCE 与Linux之间的签名验证及加解密

作者:ARM-WinCE

 

今天介绍一下WinCELinux之间如何彼此验证并解密对方的数据。我在做这个项目的时候,曾遇到过一些问题,网上搜索了一下,发现很多人遇到和我一样的问题,就是在WinCELinux之间,由于平台之间的不同,往往不能彼此验证签名或者解密对方的数据,遗憾的是,网上能够搜索到的都是提问而没有回答(当然可能是我没找到,呵呵),所以介绍一下。

 

实际上,WinCELinux之间彼此验证签名或者解密对方数据,都符合PKI标准,WinCE使用CryptoAPI函数集,Linux则支持CryptoAPIOpenssl,一般在Linux下都会使用Openssl。想在WinCELinux之间玩转PKI,要注意以下几点:

A. X509证书

X509证书有PEMDER两种编码格式,WinCE支持DER格式,Linux支持PEMDER格式,所以X509证书要选用DER格式,否则在WinCE系统中无法导入到证书库当中。

B. 私钥

私钥就是Private Key,在WinCE下使用pvk文件格式,在Linux可以是pvkpem或者der格式。

C. 字序

生成的签名或者是加密的数据,在WinCELinux下的字序是相反的,也就是说在WinCE下生成的签名和加密的数据,要进行反转,然后在Linux下才能被验证和解密,同理在Linux下也是一样的。

D. 算法一致

确认在WinCELinux之间所使用的各种算法是一致的,否则肯定是解不出来的。

 

搭建环境很简单,一个WinXP安装了WinCE开发环境,去www.openssl.org 上面下载Windows版本的Openssl安装在PC上面,网上搜索一个叫pvktool的工具,用于将私钥从PEM格式转换成PVK格式。

1. Openssl中验证WinCE文件签名

(1) Windows版本的Openssl是基于命令行的,首先在Openssl中创建一个私钥,然后从私钥当中导出公钥,命令如下:

genrsa -out private.pem 1024

创建1024bitsPEM格式的私钥private.pem

rsa -pubout -in private.pem -out public.pem

基于私钥private.pem导出PEM格式的公钥public.pem

(2) 转换私钥为PVK格式,这样可以被WinCE系统使用,命令如下:

rsa -in private.pem -outform PVK -pvk-strong -out private.pvk

private.pem私钥转换为PVK格式的私钥private.pvk

(3) 将私钥文件拷贝到WinCE系统当中,然后导入私钥,关于如何导入,在前几篇Blog中介绍过,这里不再重复了。

(4) 创建一个文件,然后对文件进行签名,签名的Hash算法这里使用SHA256,当然也可以用别的,这个在前面的Blog中也介绍过了,这里不再重复,签名成功后,将签名数据保存成文件。

(5) 将原文件和签名文件拷贝到Openssl的安装目录下面,然后在命令行模式下调用Openssl命令通过公钥对签名进行验证,命令如下:

dgst –sha256 -verify public.pem -signature signature.bin data.txt

其中public.pemPEM格式的公钥,signature.binWinCE签名后生成的签名文件,data.txt是原文件。

(6) 如果验证成功,会显示Verified或者OK之类的提示,否则会显示错误。

 

2. WinCE中验证Openssl的签名

(1) 首先在Openssl中创建一个私钥,然后从私钥当中导出DER格式的公钥,命令如下:

genrsa -out private.pem 1024

创建1024bitsPEM格式的私钥private.pem

rsa -in private.pem -pubout -outform DER -out public.der

基于私钥private.pem导出DER格式的公钥public.der

(2) 创建一个文件,然后在Openssl中对文件进行签名,命令行如下:

dgst –sha256 -sign private.pem -out signature.bin data.txt

这里Hash算法使用SHA256,私钥为private.pem,被签名文件是data.txt,生成的签名文件是signature.bin

(3) 将被签名文件,签名文件还有DER格式的公钥拷贝到WinCE系统当中。

(4) 导入公钥,读取被签名文件和签名文件,然后调用CryptVerifySignature函数对签名进行验证,在上一篇Blog中介绍过,不重复了,如果验证成功,函数返回成功,否则失败。

 

3. WinCE解密Openssl加密的数据

(1) 首先在Openssl中创建一个私钥,然后从私钥当中导出公钥,命令如下:

genrsa -out private.pem 1024

创建1024bitsPEM格式的私钥private.pem

rsa -pubout -in private.pem -out public.pem

基于私钥private.pem导出PEM格式的公钥public.pem

(2) 转换私钥为PVK格式,这样可以被WinCE系统使用,命令如下:

rsa -in private.pem -outform PVK -pvk-strong -out private.pvk

private.pem私钥转换为PVK格式的私钥private.pvk

(3) 将私钥文件拷贝到WinCE系统当中,然后导入私钥,关于如何导入,在前几篇Blog中介绍过,这里不再重复了。

(4) Openssl命令行下通过公钥对数据文件进行加密,命令行如下:

rsautl -encrypt -inkey public.pem -pubin -in file.txt -out file.ssl

通过PEM格式的公钥public.pem对文件file.txt加密,生成file.ssl

(5) file.ssl拷贝到WinCE系统中,读取文件数据,然后对文件进行解密,解密函数如下:

BOOL CryptDecrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE* pbData, DWORD* pdwDataLen)

hKey:              导入私钥的句柄

hHash:            Hash对象的句柄,这里设置为0

Final:               是否是最后要被解密的数据

dwFlags:         设置为0

pbData:           作为输入,表示要被解密的数据,作为输出,是解密后的数据

pdwDataLen:  作为输入,表示被解密数据的长度,作为输出,表示解密后数据的长度

函数调用成功,返回TRUE

 

4. Openssl解密WinCE加密的数据

(1) Openssl中创建一个私钥,然后从私钥当中导出DER格式的公钥,命令如下:

genrsa -out private.pem 1024

创建1024bitsPEM格式的私钥private.pem

rsa -in private.pem -pubout -outform DER -out public.der

基于私钥private.pem导出DER格式的公钥public.der

(2) WinCE中导入公钥,并通过公钥对文件进行加密,生成加密文件,函数如下:

/********************************************************************************

* FUNCTION NAME: Cert_Encrypt  

*

* DESCRIPTION:    Use the public key to encrypt the data

*

* INPUT PARAMETERS:

*                   puc_PubKey:                 The public key

*                             dw_Len:                       The length of public key

*                             puc_Random:             The random data to be encrypted

*                             dw_RanLen:              The length of random data

*

* OUTPUT PARAMETERS:

*                             puc_Encrypted:          The encrypted data

*

* RETURN VALUE:

*                   TRUE:           Success

*                             Others:           Failed

*

* SPECIAL CONSIDERATIONS:

*                   <none>

*********************************************************************************/

DWORD Cert_Encrypt(BYTE* puc_PubKey, DWORD dw_Len, BYTE* puc_Random, DWORD dw_RanLen, BYTE* puc_Encrypted)

{

      CERT_PUBLIC_KEY_INFO keyinfo;

      HCRYPTKEY hPubKey;

      HCRYPTPROV hProv;

      unsigned char uc_FileBuf[1024];

      DWORD dw_Loop, dw_RealSize;

      BOOL b_Ret;

 

      b_Ret = FALSE;

      // Get handle to the default provider.

    if (CryptAcquireContext(&hProv, gtc_KeyContainer, NULL, PROV_RSA_AES, 0) == TRUE)

      {

            keyinfo.Algorithm.pszObjId = OID_PUBLICKEY;

            keyinfo.Algorithm.Parameters.cbData = 0;

            keyinfo.Algorithm.Parameters.pbData = NULL;

 

            keyinfo.PublicKey.pbData = puc_PubKey;

            keyinfo.PublicKey.cbData = dw_Len;

            if (CryptImportPublicKeyInfoEx(hProv, X509_ASN_ENCODING, &keyinfo, 0, 0, NULL, &hPubKey) == TRUE)

            {

                  memcpy(uc_FileBuf, puc_Random, dw_RanLen);

                  dw_RealSize = dw_RanLen;

                  if (CryptEncrypt(hPubKey, NULL, TRUE, 0, uc_FileBuf, &dw_RealSize, sizeof(uc_FileBuf)) == TRUE)

                  {

                        for (dw_Loop = 0; dw_Loop < dw_RealSize; dw_Loop ++)

                        {

                              puc_Encrypted[dw_RealSize - 1 - dw_Loop] = uc_FileBuf[dw_Loop];

                        }

                        b_Ret = TRUE;

                  }

            }

    }

 

      CryptReleaseContext(hProv, 0);

 

 

      return b_Ret;

}

 

(3) 将加密后的数据生成文件file.ssl,然后拷贝到Openssl目录下,调用命令对加密文件进行解密,命令如下:

rsautl -decrypt -inkey private.pem -in file.ssl -out decrypted.txt

PEM格式的私钥private.pem对加密文件file.ssl进行解密,并生成decrypted.txt文件。

 

 

这里介绍了WinCELinux之间签名和加解密数据的验证,只是一个例子,可以用于程序的调试。在真正的系统中,WinCELinux都应该彼此拥有自己的私钥,并将公钥发给对方,用私钥对文件签名,用公钥验证签名,用公钥加密数据,用私钥解密数据。关于PKI基础知识,这里给个连接:

http://www.youdzone.com/signature.html

 

多说一句,公钥是不能直接发送给接收方的,因为接收方凭什么相信你呢?所以首先你要向CA提交证书请求,证书中包含公钥,CA对你的请求进行认证后会对你的证书进行签名,然后你可以将这个被CA签名的证书发给接收方,接收方拥有CA的证书,接收方会从CA的证书中取出公钥,然后对接收到的证书进行验证签名,如果验证成功,表示这个证书被CA签过名,是可信任的,然后才会信任发送方,从而从中获得发送方的公钥。接下来就可以验证发送方的签名,并加密数据了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值