iOS使用openssl库以及DSA加密

详细看参考文章,有几处坑的地方注意

1、引入库的地址问题

Openssl_DSA.m 中引入采用

#include "include/openssl/dsa.h"
#include "include/openssl/md5.h"
#include "include/openssl/pem.h"

2、include/openssl 的引入路径问题,不可以使用编译完成后的 #include <openssl/***.h> 会提示找不到路径,得修改成 #include "***.h"

3、这是修改好后的链接,有需要的可以拿去使用,不过是基于 iPhone15.5SDK版本,链接

iOS版编译完成的OpenSSL库-IOS文档类资源-CSDN下载

4、有个巨坑的地方,iOS的sha1方法,签名后的数据本地提示验签通过,但是java和c++端就无法通过,需要使用openssl进行sha1摘要解析,修改代码如下:

.h 部分

//
//  Openssl_DSA.h
//  ParkingMapSDK
//
//  Created by kk on 2022/6/22.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Openssl_DSA : NSObject

- (NSData *)sign:(NSData *)data;

- (void)setUpPrivateKey:(NSString *)privateKey;
- (void)setUpPublicKey:(NSString *)publicKey;
- (BOOL)verify:(NSData *)data withSignData:(NSData *)signData;

@end

NS_ASSUME_NONNULL_END

.m 部分

//
//  Openssl_DSA.m
//  ParkingMapSDK
//
//  Created by kk on 2022/6/22.
//

#import "Openssl_DSA.h"
#include "include/openssl/dsa.h"
#include "include/openssl/md5.h"
#include "include/openssl/pem.h"

#include "include/openssl/evp.h"

@interface Openssl_DSA (){
   DSA* _privateDSAKey;
   DSA* _publicDSAKey;
}
@end

@implementation Openssl_DSA
/*对数据进行签名
@param data 要签名的数据
@return 签名后数据
*/
- (NSData *)sign:(NSData *)data{
   if (_privateDSAKey == nil) {
       return nil;
   }
    
   // 重点在这里,使用openssl进行 sha1,不要使用iOS的sha1
   EVP_MD_CTX *pMdCtx = EVP_MD_CTX_new();
   EVP_DigestInit(pMdCtx,EVP_sha1());
   EVP_DigestUpdate(pMdCtx, (const unsigned char *) data.bytes, (int)data.length);
   unsigned char digest[2048] = {0};
   unsigned int dgst_len = 0;
   EVP_DigestFinal(pMdCtx, digest, &dgst_len);
    
   unsigned int sig_len = 0;
   unsigned char sign_string[2048] = {0};
    
   int res = DSA_sign(NID_dsaWithSHA1, digest, dgst_len, sign_string, &sig_len, _privateDSAKey);
   
   if ( 1 == res ) {
       return [[NSData alloc] initWithBytes:sign_string length:sig_len];
   }
    
   EVP_MD_CTX_free(pMdCtx);
   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 privateKey 私钥
*/
- (void)setUpPrivateKey:(NSString *)privateKey {
   BIO *bio = BIO_new_mem_buf((void *)[privateKey cStringUsingEncoding:NSUTF8StringEncoding], -1);
//    BIO *bio = BIO_new(BIO_s_mem());
//    BIO_puts(bio, [privateKey cStringUsingEncoding:NSUTF8StringEncoding]);
   _privateDSAKey = PEM_read_bio_DSAPrivateKey(bio, NULL, NULL, NULL);
   BIO_free(bio);
}

/*使用dsa公钥
@param publicKey 公钥
*/
- (void)setUpPublicKey:(NSString *)publicKey {
    BIO *bio = BIO_new_mem_buf((void *)[publicKey cStringUsingEncoding:NSUTF8StringEncoding], -1);
//    BIO *bio = BIO_new(BIO_s_mem());
//    BIO_puts(bio, [publicKey cStringUsingEncoding:NSUTF8StringEncoding]);
    _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;
}

@end

// 使用
    Openssl_DSA *dsa = [Openssl_DSA new];
    // 私钥
    [dsa setUpPrivateKey: PRIVATE_KEY];
    // 公钥
    [dsa setUpPublicKey: PUBLIC_KEY];
    NSString *sign = @"123";
    NSData *sha1Data = [sign dataUsingEncoding:NSUTF8StringEncoding];
    NSData *dsaSignData = [dsa sign:sha1Data];
    NSString *signStr = [GTMBase64 stringByEncodingData:dsaSignData];

参考文章:

1. Xcode 引入openssl的教程 - 简书

2.iOS端使用DSA加密_hherima的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我来依次回答你的两个问题。 ## 1. openssl使用 OpenSSL是一个强大的开源加密工具包,可以用于加密、解密、签名和验证数据等操作。 具体使用方法如下: 1. 安装OpenSSL:可以从官网下载安装包,根据操作系统安装。 2. 生成密钥对:使用openssl命令生成公私钥对。 ```bash openssl genrsa -out rsa_private_key.pem 2048 openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem ``` 3. 加密数据:使用公钥加密数据。 ```bash openssl rsautl -encrypt -in plaintext.txt -out ciphertext.txt -inkey rsa_public_key.pem -pubin ``` 4. 解密数据:使用私钥解密数据。 ```bash openssl rsautl -decrypt -in ciphertext.txt -out plaintext.txt -inkey rsa_private_key.pem ``` 5. 签名数据:使用私钥对数据进行签名。 ```bash openssl dgst -sha256 -sign rsa_private_key.pem -out signature.bin plaintext.txt ``` 6. 验证签名:使用公钥对签名进行验证。 ```bash openssl dgst -sha256 -verify rsa_public_key.pem -signature signature.bin plaintext.txt ``` ## 2. C#加密和数字签名 C#也提供了加密和数字签名的功能,可以使用System.Security.Cryptography命名空间下的类来实现。 具体使用方法如下: 1. 生成密钥对:使用RSACryptoServiceProvider类生成公私钥对。 ```csharp RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048); string privateKey = rsa.ToXmlString(true); string publicKey = rsa.ToXmlString(false); ``` 2. 加密数据:使用公钥加密数据。 ```csharp byte[] data = Encoding.UTF8.GetBytes("Hello World!"); byte[] encryptedData = rsa.Encrypt(data, false); ``` 3. 解密数据:使用私钥解密数据。 ```csharp byte[] decryptedData = rsa.Decrypt(encryptedData, false); string plaintext = Encoding.UTF8.GetString(decryptedData); ``` 4. 签名数据:使用私钥对数据进行签名。 ```csharp byte[] data = Encoding.UTF8.GetBytes("Hello World!"); byte[] signature = rsa.SignData(data, new SHA256CryptoServiceProvider()); ``` 5. 验证签名:使用公钥对签名进行验证。 ```csharp bool verified = rsa.VerifyData(data, new SHA256CryptoServiceProvider(), signature); ``` 以上就是关于openssl使用和C#加密和数字签名的简单介绍,希望能对你有所帮助。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值