iOS端使用DSA加密

Posted hherima

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS端使用DSA加密相关的知识,希望对你有一定的参考价值。

    ios 使用RSA就不说了,系统支持RSA。但是DSA只有mac os支持。所有APP需要DSA签名就需要借助openSSL库了。openSSL库有人编译好了,也可以自己编译(https://github.com/x2on/OpenSSL-for-iPhone

    第一步、下载上面的github中的代码。cd 到OpenSSL-for-iPhone-master工程路径输入命令:./build-libssl.sh(需要跑一会才执行完 )

批处理文件会编译多个平台的库,我们用universal的就行

第二步、将上面生成的lib和include放到自己的工程中。跟添加普通第三方库一样。

第三步、写一个类,处理公钥,私钥,签名和验证。这里直接上代码Openssl_DSA.h Openssl_DSA.m

#import <Foundation/Foundation.h>

@interface Openssl_DSA : NSObject
- (void)setUpPrivateKey:(NSString *)privateKey withPublicKey:(NSString *)publicKey;
- (NSData *)sign:(NSData *)data;
- (BOOL)verify:(NSData *)data withSignData:(NSData *)signData;
@end

#import "Openssl_DSA.h"
#import <openssl/md5.h>
#import <openssl/dsa.h>
#include <openssl/pem.h>
@interface Openssl_DSA ()
    DSA* _privateDSAKey;
    DSA* _publicDSAKey;

@end
@implementation Openssl_DSA
/*对数据进行签名
 @param data 要签名的数据
 @return 签名后数据
 */
- (NSData *)sign:(NSData *)data 
    if (_privateDSAKey == nil) 
        return nil;
    
    int dsaSize = DSA_size(_privateDSAKey);
    
    unsigned char *signBuf = (unsigned char *)calloc(dsaSize, 1);
    memset(signBuf, 0, dsaSize *sizeof(unsigned char));
    unsigned int signBufLength = 0;
    
    int res = DSA_sign(0, (const unsigned char *) data.bytes, (int)data.length, signBuf, &signBufLength, _privateDSAKey);
    
    if ( 1 == res ) 
        return [NSData dataWithBytesNoCopy:signBuf length:signBufLength];
    
    
    free(signBuf);
    return nil;

/*使用dsa公钥与私钥
 @param privateKey 私钥
 @param publicKey 公钥
 */
- (void)setUpPrivateKey:(NSString *)privateKey withPublicKey:(NSString *)publicKey 
    
    BIO *bio = BIO_new_mem_buf((void *)[privateKey cStringUsingEncoding:NSUTF8StringEncoding], -1);
    _privateDSAKey = PEM_read_bio_DSAPrivateKey(bio, NULL, NULL, NULL);
    
    BIO_free(bio);
    
    bio = BIO_new_mem_buf((void *)[publicKey cStringUsingEncoding:NSUTF8StringEncoding], -1);
    _publicDSAKey = PEM_read_bio_DSA_PUBKEY(bio, NULL, NULL, NULL);
    BIO_free(bio);

/*进行数据的DSA验签
 @param data      原数据
 @param signData 签名后的数据
 @return 是否成功
 */

- (BOOL)verify:(NSData *)data withSignData:(NSData *)signData 
    return  DSA_verify(0, (const unsigned char *)[data bytes], (int)data.length,  (const unsigned char *)[signData bytes], (int)signData.length, _publicDSAKey) == 1;

看一个例子,验证一下

#import "Openssl_DSA.h"
#import<CommonCrypto/CommonDigest.h>

-(void)selfTest
    Openssl_DSA *dsa = [[Openssl_DSA alloc]init];
    [dsa setUpPrivateKey:@"-----BEGIN PRIVATE KEY-----\\nMIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAIaeedvToMcL+CCDm/ZC/k4lK/9zw//VdCFKbeFQpy3FaU7OZP/yFlzbMBC4S2Y1kNQ7VN1dFcR6hcFwVYHldSwyN+YRl4dw1/5kI6JkWEbOIxhm8SCzvFk2ICFWoJyC6hGle2kM3hDiqo6TJmUR+pvvQy0EtAeTe3jr/4ssVYY/AhUA1oQWWR8eDs4N1baYdLR0NFzqVf0CgYA1cg/TEVvFh1rlAYDJW8FVv0IMp4mLVYf3/xWg+ArU8MHIYOwtlPiSzzBU6mt0DSmqWSUvCi2zSJyBRvCkE4UzyQQ1FiH8kWBeW65lpW71jrXHjlvJobuvizq4g7dTDLh/Bl/TthiyndoO0+7IoAHL8DwUZa7xRIw42wtD2WQCawQWAhQw1wV66bDDt3inPevlwxOeoOEA5Q==\\n-----END PRIVATE KEY-----" withPublicKey:@"-----BEGIN PUBLIC KEY-----\\nMIIBtjCCASsGByqGSM44BAEwggEeAoGBAIaeedvToMcL+CCDm/ZC/k4lK/9zw//VdCFKbeFQpy3FaU7OZP/yFlzbMBC4S2Y1kNQ7VN1dFcR6hcFwVYHldSwyN+YRl4dw1/5kI6JkWEbOIxhm8SCzvFk2ICFWoJyC6hGle2kM3hDiqo6TJmUR+pvvQy0EtAeTe3jr/4ssVYY/AhUA1oQWWR8eDs4N1baYdLR0NFzqVf0CgYA1cg/TEVvFh1rlAYDJW8FVv0IMp4mLVYf3/xWg+ArU8MHIYOwtlPiSzzBU6mt0DSmqWSUvCi2zSJyBRvCkE4UzyQQ1FiH8kWBeW65lpW71jrXHjlvJobuvizq4g7dTDLh/Bl/TthiyndoO0+7IoAHL8DwUZa7xRIw42wtD2WQCawOBhAACgYBU6hRW7HI9EIH31pZEXZM6HBlIspPwhJCDXAVH/EmeiYXHI4dPcCcwPwUjriTxDIDoCfX9/zPkCin1u5LtYdZy1PDw5R6GtfRCsyD8B4deK2CCCJPx8P5Kgw3ukdxTlf3bd4snUERot3AflXXJIgOvOAvLA75PytiCoD1Gyl27BQ==\\n-----END PUBLIC KEY-----"];
    NSString* h = @"helloworld";
    NSData* hd = [h dataUsingEncoding:NSUTF8StringEncoding];
    //一般需要对原始字符串进行sha1操作,在进行签名
    NSData* d = [dsa sign:[self sha1Data:hd]];
    
    BOOL isVerify =  [dsa verify:[self sha1Data:hd] withSignData:d];
    
    if (isVerify) 
        NSLog(@"验签通过");
    else
        NSLog(@"验签失败");
    


 

注1:看看你是从pem文件还是从字符串初始化证书的。例子是从字符串。需要注意添加 -----BEGIN PRIVATE KEY-----\\n和\\n-----END PRIVATE KEY-----  公钥就是响应的格式

注2:类似RSA和DSA这种加密,相同的字符串,每次加密后。值是不一样的。

参考链接:

https://www.jianshu.com/p/16ba85db2089
https://www.jianshu.com/p/b38656443e71
https://github.com/x2on/OpenSSL-for-iPhone

http://web.chacuo.net/netdsakeypair  //在线生成DSA公钥秘钥

 

 

 

以上是关于iOS端使用DSA加密的主要内容,如果未能解决你的问题,请参考以下文章

移动端加解密

java 加密解密算法MD5/SHA1,DSA

DSA 和 RSA 有啥区别?

NodeJS加密算法(转)

ssh服务

DSA和RSA有什么区别?