大家好,我是羊小咩
前面介紹過 ECC 的觀念篇,今天來介紹 ECC 使用,由於ECC實現難度高,且 ECDH(金鑰交換),ECIES (ECC加密) ECDSA(數位簽章演算法),都要分別實現,因此要支援全部的方法,和多種曲線套件真的很少
比起 RSA 來說 ECC 套件跟資料真的少很多,但相信ECC 的發展,會越來越多
這篇就當做是拋磚塊,看能不能引出更棒想法及作法
在 Swift ECC 可以使套件 BlueECC / CryptorECC
https://github.com/Kitura/BlueECC
支援 curves
另外也可以使用原生函式庫 Apple CryptoKit
。需要iOS13+
詳細可見官方 CryptoKit 文件
Cocoapods
pod "BlueECC"
import CryptorECC
let eccPrivateKey1 = try! ECPrivateKey.make(for: .prime256v1)
//let eccPrivateKey1 = try! ECPrivateKey.make(for: .secp384r1)
let privateKeyPEM1 = eccPrivateKey1.pemString //私鑰 PEM格式
print(privateKeyPEM)
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEID7535QYt+y/ObP202MBBkbxCWmXuMbK/twNQOnf+uehoAoGCCqGSM49
AwEHoUQDQgAEJnMKq9TviSt2NRH1UV1t6AGDotMA0zmhQDxy605BzxcAhYJpBaTd
JjKERrhK+v4l6LgCm5Y7UnFvmNXHe3Qe2A==
-----END EC PRIVATE KEY-----
let privateKey = "-----BEGIN EC PRIVATE KEY----- ........ -----END EC PRIVATE KEY-----"
let eccPrivateKey = try! ECPrivateKey(key: privateKey)
print(eccPrivateKey.pemString)
let eccPublicKey = try! eccPrivateKey.extractPublicKey()
print(eccPublicKey.pemString)
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJnMKq9TviSt2NRH1UV1t6AGDotMA
0zmhQDxy605BzxcAhYJpBaTdJjKERrhK+v4l6LgCm5Y7UnFvmNXHe3Qe2A==
-----END PUBLIC KEY-----
let plainText = "Clear Text"
let encryptedData = try! plainText.encrypt(with: eccPublicKey)
print(encryptedData.base64EncodedString())
let decryptedData = try! encryptedData.decrypt(with: eccPrivateKey)
print(String(data: decryptedData, encoding: .utf8))
NodeJS ECC 相關的套件主要是 ECDH ECDSA居多
ECIES 幾乎沒幾個,原因是官方系統函式庫根本不支援ECIES 崩╰(〒皿〒)╯潰
詳情可見Node 官方Crypto 文件 https://nodejs.org/dist/latest-v14.x/docs/api/crypto.html
因此有神人就寫了一個套件 eccrypto
可支援ECDH ECDSA 以及 ECIES
https://github.com/bitchan/eccrypto
功能算完善,可惜支援曲線和演算法太少
Only secp256k1 curve, only SHA-512 (KDF), HMAC-SHA-256 (HMAC) and AES-256-CBC for ECIES
npm install eccrypto
var eccrypto = require("eccrypto");
var privateKey = eccrypto.generatePrivate();
var asn = require("asn1.js");
var der_b64 = pri_str.match(/-----$([^]+)^-----/m)[1];
var der = Buffer(der_b64, "base64");
var Key = asn.define("Key", function() {
this.seq().obj(
this.key("_n").int(),
this.key("priv").octstr()
);
});
var privateKey = Key.decode(der, "der");
var publicKey = eccrypto.getPublic(privateKey);
let textData = Buffer.from("Message"))
eccrypto.encrypt(publicKey, textData).then(function(encrypted) {
console.log(encrypted.toString())
});
eccrypto.decrypt(privateKey, encrypted).then(function(plaintext) {
console.log("Message :", plaintext.toString());
});
sslcrypto
是在 Python 簡易使用 AES, ECIES ECDSA 套件
sslcrypto 支援度就非常的強大,可以用橋接方式在其他語言實現
https://github.com/imachug/sslcrypto
ECIES
The following curves are supported:
- secp112r1, secp112r2
- secp128r1, secp128r2
- secp160k1, secp160r1, secp160r2
- secp192k1, prime192v1
- secp224k1, secp224r1
- secp256k1, prime256v1
- secp384r1
- secp521r1
建立私鑰
// p-256
openssl ecparam -name prime256v1 -genkey -noout -out key.pem
// p-384
openssl ecparam -name secp384r1 -genkey -noout -out key.pem
// p-521
openssl ecparam -name secp521r1 -genkey -noout -out key.pem
計算公鑰
openssl ec -in key.pem -pubout -out public.pem
https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations
https://github.com/Kitura/BlueECC
https://www.npmjs.com/package/eccrypto
https://github.com/imachug/sslcrypto
https://developer.apple.com/documentation/cryptokit
https://nodejs.org/dist/latest-v14.x/docs/api/crypto.html