You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

是否存在可生成并签名EC密钥对的API端点?实现设备授权模拟自动化

自动化EC密钥生成与TAN签名方案(适配Postman/JMeter)

1. 自托管本地API(安全首选)

因为涉及密钥生成和签名,本地部署API可避免密钥泄露风险,用Python FastAPI快速搭建:

步骤实现

  1. 安装依赖:
    pip install fastapi uvicorn cryptography
    
  2. 编写API代码(main.py):
    from fastapi import FastAPI
    from cryptography.hazmat.primitives.asymmetric import ec
    from cryptography.hazmat.primitives import serialization, hashes
    from cryptography.hazmat.backends import default_backend
    import base64
    
    app = FastAPI()
    key_store = {}  # 生产环境建议替换为密钥管理服务(如AWS KMS、HashiCorp Vault)
    
    @app.post("/generate-ec-keypair")
    def generate_keypair(key_id: str = "default"):
        # 生成P-256(secp256r1)曲线密钥对,与你之前用的网页工具一致
        private_key = ec.generate_private_key(ec.SECP256R1(), default_backend())
        public_key = private_key.public_key()
    
        # 序列化为PEM格式
        private_pem = private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.PKCS8,
            encryption_algorithm=serialization.NoEncryption()
        ).decode("utf-8")
        public_pem = public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo
        ).decode("utf-8")
    
        key_store[key_id] = {"private": private_key, "public": public_pem}
        return {"public_key": public_pem, "key_id": key_id}
    
    @app.post("/sign-tan")
    def sign_tan(key_id: str = "default", tan: str = ""):
        if key_id not in key_store:
            return {"error": "先调用生成密钥接口创建密钥对"}
        
        private_key = key_store[key_id]["private"]
        # SHA-256withECDSA签名,匹配网页工具算法
        signature = private_key.sign(tan.encode(), ec.ECDSA(hashes.SHA256()))
        return {"signature": base64.b64encode(signature).decode("utf-8")}
    
  3. 启动服务:
    uvicorn main:app --host 0.0.0.0 --port 8000
    
  4. Postman/JMeter调用:
    • 生成密钥对:POST请求http://localhost:8000/generate-ec-keypair,可选传key_id区分多设备
    • 签名TAN:POST请求http://localhost:8000/sign-tan,携带key_id和tan参数,返回的signature直接用于授权

2. Postman内置脚本(无需额外API)

直接用Postman脚本集成jsrsasign库(和你之前的网页工具同源):

  1. 配置脚本依赖:
    进入Postman设置 → 脚本 → 添加CDN链接:https://kjur.github.io/jsrsasign/jsrsasign-all-min.js
  2. 生成密钥对脚本(预请求脚本):
    // 生成secp256r1曲线密钥对
    const kp = KEYUTIL.generateKeypair("EC", "secp256r1");
    const privateKeyPem = KEYUTIL.getPEM(kp.prvKeyObj);
    const publicKeyPem = KEYUTIL.getPEM(kp.pubKeyObj);
    
    // 存入环境变量
    pm.environment.set("ec_private_key", privateKeyPem);
    pm.environment.set("ec_public_key", publicKeyPem);
    
  3. 签名TAN脚本(预请求脚本):
    const tan = pm.environment.get("sms_tan");
    const privateKey = KEYUTIL.getKey(pm.environment.get("ec_private_key"));
    const sig = new KJUR.crypto.Signature({"alg": "SHA256withECDSA"});
    sig.init(privateKey);
    sig.updateString(tan);
    const hexSignature = sig.sign();
    // 转为Base64格式,匹配网页工具输出
    const b64Signature = hextob64(hexSignature);
    pm.environment.set("tan_signature", b64Signature);
    

3. JMeter JSR223脚本(Groovy)

利用JMeter内置的BouncyCastle库实现:

  1. 生成密钥对脚本(JSR223 PreProcessor):
    import org.bouncycastle.jce.provider.BouncyCastleProvider
    import java.security.Security
    
    Security.addProvider(new BouncyCastleProvider())
    
    // 生成secp256r1密钥对
    def keyGen = java.security.KeyPairGenerator.getInstance("EC", "BC")
    keyGen.initialize(new java.security.spec.ECGenParameterSpec("secp256r1"))
    def keyPair = keyGen.generateKeyPair()
    
    // 存入JMeter变量
    vars.put("ec_public_key", new String(java.util.Base64.getEncoder().encode(keyPair.getPublic().getEncoded())))
    vars.put("ec_private_key", new String(java.util.Base64.getEncoder().encode(keyPair.getPrivate().getEncoded())))
    
  2. 签名TAN脚本(JSR223 PreProcessor):
    import org.bouncycastle.jce.provider.BouncyCastleProvider
    import java.security.Security
    import org.bouncycastle.crypto.signers.ECDSASigner
    import org.bouncycastle.crypto.digests.SHA256Digest
    import java.util.Base64
    
    Security.addProvider(new BouncyCastleProvider())
    
    def tan = vars.get("sms_tan")
    def privateKeyBytes = Base64.getDecoder().decode(vars.get("ec_private_key"))
    def privateKey = java.security.KeyFactory.getInstance("EC", "BC").generatePrivate(new java.security.spec.PKCS8EncodedKeySpec(privateKeyBytes))
    
    // SHA-256withECDSA签名
    def signer = new ECDSASigner()
    signer.init(true, privateKey)
    def digest = new SHA256Digest()
    def tanBytes = tan.getBytes("UTF-8")
    digest.update(tanBytes, 0, tanBytes.length)
    def hash = new byte[digest.getDigestSize()]
    digest.doFinal(hash, 0)
    def signatureBytes = signer.generateSignature(hash)
    
    // 转为Base64
    def b64Signature = Base64.getEncoder().encodeToString(signatureBytes)
    vars.put("tan_signature", b64Signature)
    

内容的提问来源于stack exchange,提问作者Karthik Ravindran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 16:46:04