如何通过Byte数组构建Bouncy Castle的AsymmetricECPublicKey对象?
解决Bouncy Castle FIPSEC中从X/Y字节数组构建AsymmetricECPublicKey的问题
你使用的是Bouncy Castle的FIPS合规ECDH实现(FipsEC模块),这类API的对象构建方式和传统轻量API不同,需要基于椭圆曲线域参数,将X、Y字节数组转换为EC点后再构造公钥对象。以下是具体实现步骤:
核心转换方法
添加一个方法,将X、Y字节数组转换为AsymmetricECPublicKey:
public AsymmetricECPublicKey ConvertXYBytesToECPublicKey(byte[] xBytes, byte[] yBytes, FipsEC.DomainParameters domainParams) { // 获取对应椭圆曲线参数 ECCurve curve = domainParams.Curve; // 将X、Y字节数组解析为椭圆曲线上的点 ECPoint ecPoint = curve.CreatePoint(xBytes, yBytes); // 构建公钥参数对象 FipsEC.PublicKeyParameters pubKeyParams = new FipsEC.PublicKeyParameters(domainParams, ecPoint); // 通过FIPS合规的注册器创建公钥实例 return CryptoServicesRegistrar.CreatePublicKey(pubKeyParams); }
测试代码验证
在你的TestBC方法中,调用上述方法将转换后的X、Y字节数组转为公钥,再用于密钥协商验证:
public void TestBC() { String SecretString = ""; int j; AsymmetricKeyPair<AsymmetricECPublicKey, AsymmetricECPrivateKey> InitiatorKey = GenerateECDHKeyPair(); AsymmetricKeyPair<AsymmetricECPublicKey, AsymmetricECPrivateKey> RecipientKey = GenerateECDHKeyPair(); String RecipPublicKeyX = RecipientKey.PublicKey.W.XCoord.ToString(); String RecipPublicKeyY = RecipientKey.PublicKey.W.YCoord.ToString(); MessageBox.Show(RecipPublicKeyX + "\r\n" + RecipPublicKeyY); // 原公钥直接协商的结果 Byte[] SecretAgreementOriginal = GetSecretAgreement(InitiatorKey.PrivateKey, RecipientKey.PublicKey); // 模拟从单片机接收的X、Y字节数组 Byte[] publicX = ConvertHexStringToByteArray(RecipPublicKeyX); Byte[] publicY = ConvertHexStringToByteArray(RecipPublicKeyY); // 将字节数组转为AsymmetricECPublicKey AsymmetricECPublicKey reconstructedPubKey = ConvertXYBytesToECPublicKey(publicX, publicY, FipsEC.DomainParams.P256); // 用重构的公钥计算协商密钥 Byte[] SecretAgreementReconstructed = GetSecretAgreement(InitiatorKey.PrivateKey, reconstructedPubKey); // 输出原协商结果 for(j=0; j<SecretAgreementOriginal.Length; j++) SecretString += String.Format("{0:X2}",SecretAgreementOriginal[j]); MessageBox.Show("原协商密钥:\r\n" + SecretString); // 输出重构公钥后的协商结果(应与原结果一致) SecretString = ""; for(j=0; j<SecretAgreementReconstructed.Length; j++) SecretString += String.Format("{0:X2}",SecretAgreementReconstructed[j]); MessageBox.Show("重构公钥后的协商密钥:\r\n" + SecretString); }
关键注意事项
- 必须使用和密钥生成时一致的域参数(示例中为
FipsEC.DomainParams.P256),否则公钥合法性验证会失败 curve.CreatePoint方法会自动校验X、Y是否符合椭圆曲线方程,确保公钥的有效性- FipsEC模块的对象实例化依赖
CryptoServicesRegistrar,不能直接通过构造器创建,这是FIPS合规性的强制要求
内容的提问来源于stack exchange,提问作者russ
相关产品推荐
相关产品推荐

