1.通过MAC终端可以生成:

参考:https://www.anquanke.com/post/id/151220?from=timeline

生成EC秘钥命令:openssl ecparam -genkey -name secp256r1 > test_ecc.key     (pem)

查看命令:openssl ec -text < test_ecc.key

生成公钥:openssl ec -in test_ecc.key -pubout -out test_ec_pubkey.pem

查看曲线参数:openssl ecparam -list_curves

2.XCODE:

 key algorithm:EC 对应:kSecAttrKeyTypeEC

(https://developer.apple.com/documentation/security/ksecattrkeytypeec?language=objc)

但是过期了,现在用kSecAttrKeyTypeECSECPrimeRandom

(https://developer.apple.com/documentation/security/ksecattrkeytypeecsecprimerandom?language=objc)

对应java的secp算法

常用的非对称加密算法包括:

(1)RSA:因由 RSA 公司发明而命名,是一个支持变长密钥的公开密钥算法,需要加密的文件块的长度也是可变的;公开密钥算法总是要依据一个数学上的难题。RSA基于大素数积难分解问题,给定两个数p、q 很容易相乘得到n,而对n进行因式分解却相对困难。

(2)ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学。椭圆曲线因为用二元三次方程y^2= x^3+ ax + b来表示,类似椭圆周长计算方程而得名。公开秘钥算法要基于一个数学难题,椭圆曲线算法就是基于离散对数问题。有限域Fp上的椭圆曲线同样有加法,但已经不能给以几何意义的解释。

区块链中用到的签名算法SECP256K1

区块链中生成公钥时用到的算法是SECP256K1,是一种椭圆曲线的标准化表达方式,其中256表示该椭圆曲线是256位, K代表Koblitz curve,相对应的椭圆曲线的标准换表达还有,SECP192K1,SECP192R1,SECP224K1,SECP224R1,SECP256R1,SECP384R1,SECP521R1等。

IOS:

NSDictionary *parameters = @{
(__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeECSECPrimeRandom,
(__bridge id)kSecAttrKeySizeInBits: @192,
(__bridge id)kSecPrivateKeyAttrs: @{
(__bridge id)kSecAttrIsPermanent: @YES,
(__bridge id)kSecAttrApplicationTag: [@"my.key.tag" dataUsingEncoding:NSUTF8StringEncoding],
},
(__bridge id)kSecPublicKeyAttrs: @{
(__bridge id)kSecAttrIsPermanent: @YES,
(__bridge id)kSecAttrApplicationTag: [@"my.key.pubtag" dataUsingEncoding:NSUTF8StringEncoding],
}
};

SecKeyRef publicKey, privateKey;
OSStatus status = SecKeyGeneratePair((__bridge CFDictionaryRef)parameters, &publicKey, &privateKey);

NSData * publicKeyBits = nil;
NSData * privateKeyBits = nil;
NSString *privateKeyBitsString = nil;
if (status == errSecSuccess) {
publicKeyBits = (__bridge NSData *)((__bridge SecKeyRef)(CFBridgingRelease(publicKey)));
privateKeyBitsString = (__bridge NSString *)(privateKey);


// Remove from Keychain again:
(void)SecItemDelete((__bridge CFDictionaryRef) parameters);
}

 不知道为什么openssl生成的public key和ios security framework生成的长度并不一样

后来研究发现:

加密算法上:

[IOS]xcode生成公钥私钥_ios

从上图可以看出Java使用的是EC加密算法,长度是192bits,参数是secp192r1

[IOS]xcode生成公钥私钥_加密算法_02

上图是IOS的key pair生成API,可以看出使用的是ECSECPPrimeRandom的方式,但是生成的长度(over 200)明显是长于java的(java是75),同时这个长度我们无法进行RSA加密。

同时我们也尝试了寻找ECDSA的加密方式,下图可以看出,在IOS上生成key pair是没有的,但是签名有这个算法。

[IOS]xcode生成公钥私钥_xcode_03

因为ECDSA(Elliptic Curve Digital Signature Algorithm )是一种签名算法,而不是用于钥匙加密的。

In Wiki:

In ​​cryptography​​, the Elliptic Curve Digital Signature Algorithm (ECDSA) offers a variant of the ​​Digital Signature Algorithm​​​ (DSA) which uses ​​elliptic curve cryptography​​.

Key pair长度始终无法一致,后来发现原因是DER(Distinguished Encoding Rules)的格式不同导致的。IOS只接受和生成ASN.1 DER格式的数据。而Java生成public key接收的是X509证书认证的数据。IOS内无法对ASN.1格式数据进行X509认证,导致平台无法互通。

因此需要转换DER,通过ios第三库CryptoExportImportManager-master