123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- //
- // ECkeyUtils.m
- // RSADemo
- //
- // Created by 武建明 on 2018/6/20.
- // Copyright © 2018年 Ive. All rights reserved.
- //
- #import "ECkeyUtils.h"
- #import <openssl/pem.h>
- #import <openssl/obj_mac.h>
- #import <openssl/ecdh.h>
- @implementation ECkeyPairs
- @end
- @implementation ECkeyUtils
- typedef enum VoidType {
- VoidTypePrivate = 0,
- VoidTypePublic
- } voidType;
- static int KCurveName = NID_secp256k1; //曲线参数,需多端一致
- - (ECkeyPairs *)eckeyPairs{
- if (!_eckeyPairs) {
- _eckeyPairs = [[ECkeyPairs alloc] init];
- }
- return _eckeyPairs;
- }
- - (void)generatekeyPairs{
- // 生成公钥私钥
- EC_KEY *eckey;
- eckey = [self createNewKeyWithCurve:KCurveName];
- NSString *privatePem = [self getPem:eckey voidType:VoidTypePrivate];
- NSString *publicPem = [self getPem:eckey voidType:VoidTypePublic];
- self.eckeyPairs.privatePem = privatePem;
- self.eckeyPairs.privateKey = [ECkeyUtils getKeyFromPemKey:privatePem isPrivate:YES];
- self.eckeyPairs.publicPem = publicPem;
- self.eckeyPairs.publicKey = [ECkeyUtils getKeyFromPemKey:publicPem isPrivate:NO];
- EC_KEY_free(eckey);
- }
- + (NSString *)getShareKeyFromPeerPubPem:(NSString *)peerPubPem
- privatePem:(NSString *)privatePem
- length:(int)length{
- // 根据私钥PEM字符串,生成私钥
- EC_KEY *clientEcKey = [ECkeyUtils privateKeyFromPEM:privatePem];
- if (!clientEcKey) {
- return nil;
- }
- if (!length) {
- // 获取私钥长度
- const EC_GROUP *group = EC_KEY_get0_group(clientEcKey);
- length = (EC_GROUP_get_degree(group) + 7)/8;
- }
- NSLog(@"\n--------------------------------------------------------------需生成Sharekey长度:%d",length);
- // 根据peerPubPem生成新的公钥EC_KEY
- EC_KEY *serverEcKey = [ECkeyUtils publicKeyFromPEM:peerPubPem];
- const EC_POINT *serverEcKeyPoint = EC_KEY_get0_public_key(serverEcKey);
- char shareKey[length];
- ECDH_compute_key(shareKey, length, serverEcKeyPoint, clientEcKey, NULL);
- // 释放公钥,释放私钥
- EC_KEY_free(clientEcKey);
- EC_KEY_free(serverEcKey);
- NSData *shareKeyData = [NSData dataWithBytes:shareKey length:length];
- NSString *shareKeyStr = [shareKeyData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
- NSLog(@"\nShareKey:\n--------\n%@\n--------",shareKeyStr);
- return shareKeyStr;
- }
- /**
- 获取PEM格式的EC_KEY
- @param ecKey 目标EC_KEY
- @param voidType 方法类型
- @return 返回PEM格式的KEY
- */
- - (NSString *)getPem:(EC_KEY *)ecKey
- voidType:(voidType)voidType{
- BIO *out = NULL;
- BUF_MEM *buf;
- buf = BUF_MEM_new();
- out = BIO_new(BIO_s_mem());
- switch (voidType) {
- case VoidTypePrivate:
- PEM_write_bio_ECPrivateKey(out, ecKey, NULL, NULL, 0, NULL, NULL);
- break;
- case VoidTypePublic:
- PEM_write_bio_EC_PUBKEY(out, ecKey);
- break;
- default:
- break;
- }
- BIO_get_mem_ptr(out, &buf);
- NSString *pem = [[NSString alloc] initWithBytes:buf->data
- length:(NSUInteger)buf->length
- encoding:NSASCIIStringEncoding];
- BIO_free(out);
- return pem;
- }
- + (EC_KEY *)publicKeyFromPEM:(NSString *)publicKeyPEM {
- // 将PEM格式的公钥字符串转化成EC_KEY
- const char *buffer = [publicKeyPEM UTF8String];
- BIO *bpubkey = BIO_new_mem_buf(buffer, (int)strlen(buffer));
- EVP_PKEY *public = PEM_read_bio_PUBKEY(bpubkey, NULL, NULL, NULL);
- EC_KEY *ec_cdata = EVP_PKEY_get1_EC_KEY(public);
- BIO_free_all(bpubkey);
- return ec_cdata;
- }
- + (EC_KEY *)privateKeyFromPEM:(NSString *)privateKeyPEM {
- // 将PEM格式的私钥字符串转化成EC_KEY
- const char *buffer = [privateKeyPEM UTF8String];
- BIO *out = BIO_new_mem_buf(buffer, (int)strlen(buffer));
- EC_KEY *pricateKey = PEM_read_bio_ECPrivateKey(out, NULL, NULL, NULL);
- BIO_free_all(out);
- return pricateKey;
- }
- - (EC_KEY *)createNewKeyWithCurve:(int)curve {
- // 生成EC_KEY对象
- int asn1Flag = OPENSSL_EC_NAMED_CURVE;
- int form = POINT_CONVERSION_UNCOMPRESSED;
- EC_KEY *eckey = NULL;
- EC_GROUP *group = NULL;
- eckey = EC_KEY_new();
- group = EC_GROUP_new_by_curve_name(curve);
- EC_GROUP_set_asn1_flag(group, asn1Flag);
- EC_GROUP_set_point_conversion_form(group, form);
- EC_KEY_set_group(eckey, group);
- int resultFromKeyGen = EC_KEY_generate_key(eckey);
- if (resultFromKeyGen != 1){
- raise(-1);
- }
- return eckey;
- }
- // pem证书转换为普通证书
- + (NSString *)getKeyFromPemKey:(NSString *)pemKey isPrivate:(BOOL)isPrivate {
-
- NSString *key = [NSString string];
- key = [pemKey copy];
- key = [key stringByReplacingOccurrencesOfString:@"\n" withString:@""];
- NSRange range1, range2;
- if (isPrivate) {
- range1 = [key rangeOfString:@"-----BEGIN EC PRIVATE KEY-----"];
- range2 = [key rangeOfString:@"-----END EC PRIVATE KEY-----"];
- }else {
- range1 = [key rangeOfString:@"-----BEGIN PUBLIC KEY-----"];
- range2 = [key rangeOfString:@"-----END PUBLIC KEY-----"];
- }
-
- key = [key substringWithRange:NSMakeRange(range1.location + range1.length, range2.location - range1.location - range1.length)];
- return key;
- }
- // 普通证书转换为pem证书
- + (NSString *)getPemKeyFromKey:(NSString *)key isPrivate:(BOOL)isPrivate {
-
- NSMutableString *pemKey = [NSMutableString string];
- if (isPrivate) {
- [pemKey appendString:@"-----BEGIN EC PRIVATE KEY-----\n"];
- }else {
- [pemKey appendString:@"-----BEGIN PUBLIC KEY-----\n"];
- }
-
- // 没歌64需要插入换行符
- NSMutableString *appendStr = [key mutableCopy];
- NSInteger index = 0;
- if (appendStr.length > 64) {
- index = 64;
- }
- while (index > 0) {
- [appendStr insertString:@"\n" atIndex:index];
- NSString *str = [appendStr substringFromIndex:index + 2];
- if (str.length > 64) {
- // 设置index为插入的换行符后64的位置
- index = index + 2 + 64;
- }else {
- index = 0;
- }
- }
-
- [pemKey appendString:appendStr];
-
- if (isPrivate) {
- [pemKey appendString:@"\n-----END EC PRIVATE KEY-----"];
- }else {
- [pemKey appendString:@"\n-----END PUBLIC KEY-----"];
- }
-
- return pemKey;
- }
- @end
|