iOS生成的EC公钥Base64转Java PublicKey后结果不一致问题排查
问题:iOS生成的EC公钥Base64转Java PublicKey后重新编码不一致
尝试将iOS(Swift)生成的基于secp256r1曲线的EC公钥Base64编码字符串转换为Android平台的Java PublicKey,用于双方计算共享密钥。代码无编译或运行时异常,可成功生成PublicKey,但将其重新Base64编码后与传入的原公钥不一致。
相关代码
import android.util.Base64 import org.bouncycastle.asn1.sec.SECNamedCurves import org.bouncycastle.math.ec.ECCurve import java.math.BigInteger import java.nio.charset.StandardCharsets import java.security.* import java.security.spec.* import javax.crypto.* import javax.crypto.spec.IvParameterSpec import javax.crypto.spec.SecretKeySpec fun iosB64EncodedStrPKToPK(iOSB64EncodedPK: String): PublicKey { val decodedPK = Base64.decode(iOSB64EncodedPK, Base64.NO_WRAP) val x9ECParamSpec = SECNamedCurves.getByName("secp256r1") val curve = x9ECParamSpec.curve val point = curve.decodePoint(decodedPK) val xBcEC = point.affineXCoord.toBigInteger() val yBcEC = point.affineYCoord.toBigInteger() val gBcEC = x9ECParamSpec.g val xGBcEC = gBcEC.affineXCoord.toBigInteger() val yGBcEC = gBcEC.affineYCoord.toBigInteger() val hBcEC = x9ECParamSpec.h.toInt() val nBcEC = x9ECParamSpec.n val jPEC = ECPoint(xBcEC, yBcEC) val gJpEC = ECPoint(xGBcEC, yGBcEC) val jEllipticCurve = convertECCurveToEllipticCurve(curve, gJpEC, nBcEC, hBcEC) val eCParameterSpec = ECParameterSpec(jEllipticCurve, gJpEC, nBcEC, hBcEC) val ecPubLicKeySpec = ECPublicKeySpec(jPEC, eCParameterSpec) val keyFactorySpec = KeyFactory.getInstance("EC") return keyFactorySpec.generatePublic(ecPubLicKeySpec) } private fun convertECCurveToEllipticCurve( curve: ECCurve, ecPoint: ECPoint, n: BigInteger, h: Int ): EllipticCurve { val ecField = ECFieldFp(curve.field.characteristic) val firstCoefficient = curve.a.toBigInteger() val secondCoefficient = curve.b.toBigInteger() val ecParams = ECParameterSpec( EllipticCurve(ecField, firstCoefficient, secondCoefficient), ecPoint, n, h ) return ecParams.curve }
测试数据
- 传入的原公钥Base64字符串:
BAlWWu46il/ly6Axd/qclmhEVhGth93QN5+h3JBJEKEmhKd1LfqkpCqX1cT1cQDs9nPq9Lq0/FtZitkjr7Rqd94= - 转换后重新Base64编码得到的字符串:
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECVZa7jqKX+XLoDF3+pyWaERWEa2H3dA3n6HckEkQoSaEp3Ut+qSkKpfVxPVxAOz2c+r0urT8W1mK2SOvtGp33g==
测试代码
val pkIOS = "BAlWWu46il/ly6Axd/qclmhEVhGth93QN5+h3JBJEKEmhKd1LfqkpCqX1cT1cQDs9nPq9Lq0/FtZitkjr7Rqd94=" Log.i("SOME_TAG","PUBLIC_KEY_IOS:${Base64.encodeToString(iosB64EncodedStrPKToPK(pkIOS).encoded,Base64.NO_WRAP)}")
运行环境与依赖
运行环境为Android,使用的BouncyCastle版本为1.70:
def bouncy_castle_version = '1.70' implementation "org.bouncycastle:bcpkix-jdk15on:$bouncy_castle_version" implementation "org.bouncycastle:bcprov-jdk15on:$bouncy_castle_version"
需求:希望得到问题排查方向指引,同时欢迎推荐相关学习资料。
内容的提问来源于stack exchange,提问作者codeasus
相关产品推荐
相关产品推荐

