SDK侧Enroll获取签名源码分析
抛砖引玉,先了解一下enroll的大体的初步流程。

在用户enroll过程中有如下处理,主要剖析Fabric-sdk-java:
①由客户端发起enroll调用
②生成私钥和公钥对。
JAVA-SDK对应源码如下:
HFCAClient.java:455行
try {
String pem = req.getCsr();
KeyPair keypair = req.getKeyPair();
if (null != pem && keypair == null) {
throw new InvalidArgumentException("If certificate signing request is supplied the key pair needs to be supplied too.");
}
if (keypair == null) {
logger.debug("[HFCAClient.enroll] Generating keys...");
// generate ECDSA keys: signing and encryption keys
keypair = cryptoSuite.keyGen();
logger.debug("[HFCAClient.enroll] Generating keys...done!");
}
③在generateCertificationRequest函数中使用私钥生成签名,结合用户名,公钥生成CSR签名请求,并发送给ca服务器。
/**
* generateCertificationRequest
*
* @param subject The subject to be added to the certificate
* @param pair Public private key pair
* @return PKCS10CertificationRequest Certificate Signing Request.
* @throws OperatorCreationException
*/
public String generateCertificationRequest(String subject, KeyPair pair)
throws InvalidArgumentException {
try {
PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(
new X500Principal("CN=" + subject), pair.getPublic()); //用户名和公钥构造PKCS11证书请求
JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256withECDSA"); //指定签名算法
if (null != SECURITY_PROVIDER) {
csBuilder.setProvider(SECURITY_PROVIDER);
}
ContentSigner signer = csBuilder.build(pair.getPrivate()); //通过私钥生成签名
return certificationRequestToPEM(p10Builder.build(signer)); //构造签名请求
} catch (Exception e) {
logger.error(e);
throw new InvalidArgumentException(e);
}
}
④通过ca服务器验签,验签成功会生成签名应答,客户端根据应答结果构造X509Enrollment(keypair, signedPem);签名
if (pem == null) {
String csr = cryptoSuite.generateCertificationRequest(user, keypair);
req.setCSR(csr);
}
if (caName != null && !caName.isEmpty()) {
req.setCAName(caName);
}
String body = req.toJson();
String responseBody = httpPost(getURL(HFCA_ENROLL), body,
new UsernamePasswordCredentials(user, secret));
logger.debug("response:" + responseBody);
JsonReader reader = Json.createReader(new StringReader(responseBody));
JsonObject jsonst = (JsonObject) reader.read();
boolean success = jsonst.getBoolean("success");
logger.debug(format("[HFCAClient] enroll success:[%s]", success));
if (!success) {
throw new EnrollmentException(format("FabricCA failed enrollment for user %s response success is false.", user));
}
JsonObject result = jsonst.getJsonObject("result");
if (result == null) {
throw new EnrollmentException(format("FabricCA failed enrollment for user %s - response did not contain a result", user));
}
Base64.Decoder b64dec = Base64.getDecoder();
String signedPem = new String(b64dec.decode(result.getString("Cert").getBytes(UTF_8)));
logger.debug(format("[HFCAClient] enroll returned pem:[%s]", signedPem));
JsonArray messages = jsonst.getJsonArray("messages");
if (messages != null && !messages.isEmpty()) {
JsonObject jo = messages.getJsonObject(0);
String message = format("Enroll request response message [code %d]: %s", jo.getInt("code"), jo.getString("message"));
logger.info(message);
}
logger.debug("Enrollment done.");
return new X509Enrollment(keypair, signedPem);
结论,目前的Fabirc-SDK与软钱包过度耦合,与公链钱包和SDK分离思路不同。后期,期待Fabirc逐步在改进。
目前看到Nodejs已经率先做出改变了,是由复旦大学的妹妹与导师以及社区大牛一并完成的。
https://wiki.hyperledger.org/display/INTERN/Fabric+nodejs+SDK+security+extension
网友评论