椭圆曲线加密ECC

title: 椭圆曲线加密ECC
type: categories
date: 2017-06-23 13:39:43
categories: iOS

tags: [ECC, ECDSA, ECDH]

椭圆曲线加密是一种类似于RSA的非对称加密算法,具体介绍可以参考这篇文章http://www.itye.org/archives/3254, 写得很明白。

本文内容翻译自

openssl生成指令

https://github.com/konstantinpavlikhin/Watchdog

生成DSA密钥对

1、生成DSA私钥

$ openssl dsaparam -genkey 2048 -noout -out DSAPrivateKey.pem

2、导出公钥

openssl dsa -in DSAPrivateKey.pem -pubout -outform PEM -out DSAPublicKey.pem

生成ECDSA密钥对

1、查看支持的曲线类型,常用的如:secp521r1,secp128r1, secp192r1, secp256r1, secp384r1等

$ openssl ecparam -list_curves

2、生成ECDSA私钥

$ openssl ecparam -genkey -name secp521r1 -noout -out ECDSAPrivateKey.pem

3、从私钥中导出公钥

$ openssl ec -in ECDSAPrivateKey.pem -pubout -outform PEM -out ECDSAPublicKey.pem

Objective-C中的ECC库

https://github.com/ricmoo/GMEllipticCurveCrypto

ECDSA允许通过私钥进行签名,然后通过公钥进行验签;

ECDH是通过用户自己拥有的私钥和另一个用户的公钥来创建一个密钥,通过这个密钥在进行加密操作。

API
创建一个ECC密钥对
GMEllipticCurveCrypto *crypto = [GMEllipticCurveCrypto generateKeyPairForCurve:
                                                         GMEllipticCurveSecp192r1];
NSLog(@"Public Key: %@", crypto.publicKeyBase64);
NSLog(@"Private Key: %@", crypto.privateKeyBase64);
使用

key可以是base64加密过的字符串,也可以是data类型

crypto.publicKeyBase64 = @"AtF8hCxh9h1zlExuOZutuw+tRzmk3zVdfA==";
NSLog(@"Public Key: base64=%@, rawBinary=%@", crypto.publicKeyBase64, crypto.publicKey);

char bytes[] = { 2, 209, 124, 132, 44, 97, 246, 29, 115, 148, 76, 110, 57, 155, 173, 
                 187, 15, 173, 71, 57, 164, 223, 53, 93, 124 };
crypto.publicKey = [NSData dataWithBytes:bytes length:25];
NSLog(@"Public Key: base64=%@, rawBinary=%@", crypto.publicKeyBase64, crypto.publicKey);
签名

需要注意的是:签名的内容长度要和所选取的曲线类型一致。

用ECDSA签名的话,产生的签名是所选曲线的两倍。如:secp192k1类型的曲线,产生的签名的长度为384bit(48字节)。

还需要注意的是:因为有随机k的存在,所以每次产生的签名是不一样的。

// The first 24 bytes of the SHA-256 hash for "Hack the Planet!"
char bytes[] = { 56, 164, 34, 250, 121, 21, 2, 18, 65, 4, 161, 90, 126, 145, 111, 204, 
                 151, 65, 181, 4, 231, 177, 117, 154 };
NSData *messageHash = [NSData dataWithBytes:bytes length:24];

GMEllipticCurveCrypto *crypto = [GMEllipticCurveCrypto cryptoForCurve:
                                                GMEllipticCurveSecp192r1];
crypto.privateKeyBase64 = @"ENxb+5pCLAGT88vGmE6XLQRH1e8i/0rz";
NSData *signature = [crypto signatureForHash:messageHash];
NSLog(@"Signature: %@", signature);
验签
rypto = [GMEllipticCurveCrypto cryptoForCurve:GMEllipticCurveSecp192r1];
crypto.publicKeyBase64 = @"AtF8hCxh9h1zlExuOZutuw+tRzmk3zVdfA==";;
BOOL valid = [crypto verifySignature:signature forHash:messageHash];
NSLog(@"Valid Signature: %@", (valid ? @"YES": @"NO"));
密钥的交换

使用ECDH方式生成与选取的曲线类型相同长度的交换密钥,如,192bit的曲线产生的是192bit的密钥。

NSString *alicePublicKey = @"A9N+XWIjLCYAwa8Hb7T6Rohttqo91CF8HQ==";
NSString *alicePrivateKey = @"frs4puAKipcbevvwJb7l77xACgB/FyBv";

NSString *bobPublicKey = @"A35aoteno4wnAdJgV8AXKKl1AfPVRrSZQA==";
NSString *bobPrivateKey = @"LP83qv81MsXVyPOFV7V5jKVOoU4DKPUS";


// Alice performs...
GMEllipticCurveCrypto *alice = [GMEllipticCurveCrypto cryptoForCurve:
                                               GMEllipticCurveSecp192r1];
alice.privateKeyBase64 = alicePrivateKey;
NSData *aliceSharedSecret = [alice sharedSecretForPublicKeyBase64:bobPublicKey];
NSLog(@"Shared Secret Alice: %@", aliceSharedSecret);

// Bob performs...
GMEllipticCurveCrypto *bob = [GMEllipticCurveCrypto cryptoForCurve:
                                             GMEllipticCurveSecp192r1];
bob.privateKeyBase64 = bobPrivateKey;
NSData *bobSharedSecret = [bob sharedSecretForPublicKeyBase64:alicePublicKey];
NSLog(@"Shared Secret Bob: %@", bobSharedSecret);

// And now both parties have the same secret!
NSLog(@"Shared secrets equal? %d", [aliceSharedSecret isEqualToData:bobSharedSecret]);

部分原文

Elliptic Curve Crypto

An Objective-C library for Elliptic Curve Digital Signing Algorithm (ECDSA) and for Elliptic Curve Diffie-Hellman (ECDH).

ECDSA allows signatures to be generated using a private key and validated using a public key.

ECDH allows two identities to use their own private keys and each other’s public key to generate a shared secret, which can then be used for encryption.

This library is largely based on the easy-ecc library (https://github.com/kmackay/easy-ecc).

Features

  • Supports: secp128r1, secp192r1, secp256r1, secp384r1
  • Automatically detects curve based on private or public key
  • Supports keys as raw bytes or as base64 encoded strings
  • BSD 2-clause license

API

Generate a new ECC key pair

GMEllipticCurveCrypto *crypto = [GMEllipticCurveCrypto generateKeyPairForCurve:
                                                         GMEllipticCurveSecp192r1];
NSLog(@"Public Key: %@", crypto.publicKeyBase64);
NSLog(@"Private Key: %@", crypto.privateKeyBase64);

Using keys

Keys can be accessed and set interchangably in either raw bytes or as base64 encoded strings.

crypto.publicKeyBase64 = @"AtF8hCxh9h1zlExuOZutuw+tRzmk3zVdfA==";
NSLog(@"Public Key: base64=%@, rawBinary=%@", crypto.publicKeyBase64, crypto.publicKey);

char bytes[] = { 2, 209, 124, 132, 44, 97, 246, 29, 115, 148, 76, 110, 57, 155, 173, 
                 187, 15, 173, 71, 57, 164, 223, 53, 93, 124 };
crypto.publicKey = [NSData dataWithBytes:bytes length:25];
NSLog(@"Public Key: base64=%@, rawBinary=%@", crypto.publicKeyBase64, crypto.publicKey);

Generate a signature for a message

The signing operations require a message the same length as the curve; so generally, a hash algorithm is used to fix the original message’s length.

Signatures using ECDSA will be twice the curve size. So, the 192 bit curve will produce a signature that is 48 bytes (384 bits) long.

Also note that the signature is intentionally different each time because ECDSA uses a random k value.

// The first 24 bytes of the SHA-256 hash for "Hack the Planet!"
char bytes[] = { 56, 164, 34, 250, 121, 21, 2, 18, 65, 4, 161, 90, 126, 145, 111, 204, 
                 151, 65, 181, 4, 231, 177, 117, 154 };
NSData *messageHash = [NSData dataWithBytes:bytes length:24];

GMEllipticCurveCrypto *crypto = [GMEllipticCurveCrypto cryptoForCurve:
                                                GMEllipticCurveSecp192r1];
crypto.privateKeyBase64 = @"ENxb+5pCLAGT88vGmE6XLQRH1e8i/0rz";
NSData *signature = [crypto signatureForHash:messageHash];
NSLog(@"Signature: %@", signature);

Verify a signature

// messageHash and signature from above

crypto = [GMEllipticCurveCrypto cryptoForCurve:GMEllipticCurveSecp192r1];
crypto.publicKeyBase64 = @"AtF8hCxh9h1zlExuOZutuw+tRzmk3zVdfA==";;
BOOL valid = [crypto verifySignature:signature forHash:messageHash];
NSLog(@"Valid Signature: %@", (valid ? @"YES": @"NO"));

Shared secret

Shared secrets using ECDH are the same length as the curve. So, the 192 bit curve will produce a shared secret that is 24 bytes (192 bits) long.

NSString *alicePublicKey = @"A9N+XWIjLCYAwa8Hb7T6Rohttqo91CF8HQ==";
NSString *alicePrivateKey = @"frs4puAKipcbevvwJb7l77xACgB/FyBv";

NSString *bobPublicKey = @"A35aoteno4wnAdJgV8AXKKl1AfPVRrSZQA==";
NSString *bobPrivateKey = @"LP83qv81MsXVyPOFV7V5jKVOoU4DKPUS";


// Alice performs...
GMEllipticCurveCrypto *alice = [GMEllipticCurveCrypto cryptoForCurve:
                                               GMEllipticCurveSecp192r1];
alice.privateKeyBase64 = alicePrivateKey;
NSData *aliceSharedSecret = [alice sharedSecretForPublicKeyBase64:bobPublicKey];
NSLog(@"Shared Secret Alice: %@", aliceSharedSecret);

// Bob performs...
GMEllipticCurveCrypto *bob = [GMEllipticCurveCrypto cryptoForCurve:
                                             GMEllipticCurveSecp192r1];
bob.privateKeyBase64 = bobPrivateKey;
NSData *bobSharedSecret = [bob sharedSecretForPublicKeyBase64:alicePublicKey];
NSLog(@"Shared Secret Bob: %@", bobSharedSecret);

// And now both parties have the same secret!
NSLog(@"Shared secrets equal? %d", [aliceSharedSecret isEqualToData:bobSharedSecret]);

Convenience functions

Automatically detects curve and sets up the private or public key

+ (GMEllipticCurveCrypto*)cryptoForKey: (NSData*)privateOrPublicKey;
+ (GMEllipticCurveCrypto*)cryptoForKeyBase64: (NSString*)privateOrPublicKey;

Automatically hash and compute the signature for a message

Include the GMEllipticCurveCrypto+hash.h category to hash data automatically before signing and verifying. The hash algorithm used must be at least the length of the curve. The hash will have the right-most bytes truncated, if necessary.

- (NSData*)hashSHA256AndSignData: (NSData*)data;
- (BOOL)hashSHA256AndVerifySignature: (NSData*)signature forData: (NSData*)data;

- (NSData*)hashSHA384AndSignData: (NSData*)data;
- (BOOL)hashSHA384AndVerifySignature: (NSData*)signature forData: (NSData*)data;

Why?

Kenneth MacKay’s easy-ecc is an awesome, simple-to-use implementation of essential Elliptic Curve Cryptographic functions, however, the curve used is specified as a compile-time constant, so it cannot be changed at runtime.

This library allows any and as many different curves to be used at once.

Donations?

Sure! :-)

Bitcoin - 1LNdGsYtZXWeiKjGba7T997qvzrWqLXLma

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值