C#实现PACE PIN通用映射时遇6984(DATA_INVALID)错误求助
使用ECC实现带通用映射的PACE PIN认证时发送PKPCD,map遭遇6984错误排查
我正尝试使用椭圆曲线实现带通用映射的PACE PIN认证,在执行「发送PKPCD,map并接收PKPICC,map」步骤时遇到6984错误。6984错误表示DATA_INVALID:给定数据或卡内数据(如保存的挑战值)无效。
参考资料
- GitHub文档
- ICAO 9303第11部分手册
自定义卡ECC参数
Using ECC-NIST 256 curve for the domain parameters # Private ECC key (Generated from a RNG) d_pace_ecdh_card_private=0029482318BE67844AE13D6C2CD672AE69525F9016496DF15AF141BB26E901EB prime=FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF a=FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC order=FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551 b=5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B G_X= basepoint=6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5 # Calculate Ecc public key (Q=d_pace_ecdh_card_private*basepoint) pace_ecdh_public=046CEC918BFBE1198005718DEA22D2139C856B66326B66A8AF769DAADB4D4F439B56A161713158746F8D3117F097972B1F9CB2382E54A3AF2D61FAA30ED1FEF436
实现代码
public void paceGenericMapping() { // Paramètres du domaine pour la courbe ECC-NIST 256 X9ECParameters curve = SecNamedCurves.GetByName("secp256r1"); // Utilisation des paramètres déjà connus Org.BouncyCastle.Math.BigInteger prime = new Org.BouncyCastle.Math.BigInteger("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 16); Org.BouncyCastle.Math.BigInteger a = new Org.BouncyCastle.Math.BigInteger("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 16); Org.BouncyCastle.Math.BigInteger order = new Org.BouncyCastle.Math.BigInteger("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 16); Org.BouncyCastle.Math.BigInteger b = new Org.BouncyCastle.Math.BigInteger("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", 16); Org.BouncyCastle.Math.BigInteger G_X = new Org.BouncyCastle.Math.BigInteger("6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", 16); Org.BouncyCastle.Math.BigInteger G_Y = new Org.BouncyCastle.Math.BigInteger("4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", 16); Org.BouncyCastle.Math.EC.ECPoint basePoint = curve.Curve.CreatePoint(G_X, G_Y); ECDomainParameters domainParams = new ECDomainParameters(curve.Curve, basePoint, order, curve.H, curve.GetSeed()); // • Read EF.DIR and EF.CardAccess (applet capabilities) string selectEF_F000 = executeCommande("00A40000023F00"); string selectEF_CardAccess = executeCommande("00a4020c02011c"); string read_binary_1 = executeCommande("00b0000005"); string read_binary_2 = executeCommande("00b000055b"); // • Select algorithm (INS 22) string setMSE = executeCommande("0022c1a412800a04007f0007020204020283010384010c"); // • The host requests PACE for authentication, possibly giving a preference : string paceAuthenticationREQUEST = executeCommande("10860000027c0000"); // • The card responds with a 128-bit (16 byte) random number (nonce) encrypted with PACE_nonce_AES128key : 7C 12 80 10 <encrypted_nonce> int startIndex = paceAuthenticationREQUEST.IndexOf("7C128010") + "7C128010".Length; // Trouver l'index de fin de la sous-chaîne int endIndex = paceAuthenticationREQUEST.IndexOf("9000", startIndex); // Extraire la sous-chaîne : representant Key: z - encrypted nonce (z [PACE]) string encryptedNonce = paceAuthenticationREQUEST.Substring(startIndex, endIndex - startIndex); // the host decrypts the 128-bit nonce with PACE_nonce_AES128key derived from user input as described above byte[] bytesEncryptedNonce = StringToByteArray(encryptedNonce); // Key: K - derived key from shared secret : trouver la clé dérivée du PIN string derivedKeySH = calculerSHA1("3132333400000003"); byte[] bytesDerivedKeySH = StringToByteArray(derivedKeySH); // • [decrypt nonce nonce] byte[] bytesDecryptedNonce = decryptAES(bytesEncryptedNonce, bytesDerivedKeySH); string decryptedNonce = byteToHexStr(bytesDecryptedNonce); Org.BouncyCastle.Math.BigInteger nonce = new Org.BouncyCastle.Math.BigInteger(decryptedNonce, 16); // • [generate random number as private key SKPCD for DHKA] SecureRandom random = new SecureRandom(); Org.BouncyCastle.Math.BigInteger SKPCD = new Org.BouncyCastle.Math.BigInteger(domainParams.Curve.Order.BitLength, random).Mod(domainParams.Curve.Order); // • [calculate ephermeral PKPCD = BasePoint G * SKPCD] Org.BouncyCastle.Math.EC.ECPoint PKPCD = domainParams.G.Multiply(SKPCD); // Convertir les coordonnées X et Y en hexadécimal string PKPCDXHex = PKPCD.XCoord.ToBigInteger().ToString(16); string PKPCDYHex = PKPCD.YCoord.ToBigInteger().ToString(16); // • Send PKPCD and Receive PKPICC from card string requestPKicc = "10860000457C43814104" + PKPCDXHex + PKPCDYHex + "00"; string reponsePKicc = executeCommande(requestPKicc); // Définir les positions de début et de fin de la sous-chaîne int entete = 10; // Après les 4 premiers octets int sw = reponsePKicc.Length - 4; // Avant les 4 derniers octets // Extraire la sous-chaîne reponsePKicc = reponsePKicc.Substring(entete, sw - entete); string PKICCXHex = reponsePKicc.Substring(0, reponsePKicc.Length/2); string PKICCYHex = reponsePKicc.Substring(reponsePKicc.Length / 2); Org.BouncyCastle.Math.EC.ECPoint PKPICC = curve.Curve.CreatePoint(new Org.BouncyCastle.Math.BigInteger(PKICCXHex, 16), new Org.BouncyCastle.Math.BigInteger(PKICCYHex, 16)); // • [build shared secret: H = PKPICC * SKPCD = G * SKPICC * SKPCD] Org.BouncyCastle.Math.EC.ECPoint H = PKPICC.Multiply(SKPCD); // • [build new base point:] : Gmap = G * s + H = G * s + G * SKPICC * SKPCD = G * (s + SKPICC * SKPCD) Org.BouncyCastle.Math.EC.ECPoint Gmap = basePoint.Multiply(nonce); Gmap = Gmap.Add(H); // • [generate random number as private key SKPCD,map for DHKA] Org.BouncyCastle.Math.BigInteger SKPCDMap = new Org.BouncyCastle.Math.BigInteger(Gmap.Curve.Order.BitLength, random).Mod(Gmap.Curve.Order); // • [calculate ephermeral PKPCD,map = BasePoint Gmap * SKPCD,map] Org.BouncyCastle.Math.EC.ECPoint PKPCDMap = Gmap.Multiply(SKPCDMap); // Convertir les coordonnées X et Y en hexadécimal string PKPCDMapXHex = PKPCDMap.XCoord.ToBigInteger().ToString(16); string PKPCDMapYHex = PKPCDMap.YCoord.ToBigInteger().ToString(16); // • Send PKPCD,map and Receive PKPICC,map from card string requestPKpcdmap = "10860000457c43834104" + PKPCDMapXHex + PKPCDMapYHex + "00"; string responsePKpcdmap = executeCommande(requestPKpcdmap); }
恳请协助排查该6984错误的原因及解决方法。
内容的提问来源于stack exchange,提问作者Bouls
相关产品推荐
相关产品推荐

