How to Secure API Calls with Hybrid Symmetric‑Asymmetric Encryption and HTTPS
This guide explains a comprehensive API encryption scheme that combines symmetric and asymmetric cryptography, HTTPS principles, and WeChat Pay encryption to protect against crawlers, tampering, replay attacks, and ensure data integrity, complete with design rationale, implementation steps, code examples, and security analysis.
Background and Goal
With the rapid development of network technology, data‑security problems have become increasingly prominent. This solution combines HTTPS principles with WeChat Pay encryption, employing symmetric encryption, asymmetric encryption, hashing, and signature algorithms to protect API requests against crawlers, request tampering, replay attacks, and to verify data integrity.
Design Overview
Cryptographic Primitives
Symmetric encryption : Fast, low‑cost encryption using a shared secret key. Used for encrypting the actual request and response payloads.
Asymmetric encryption : RSA public‑private key pair. Used only to encrypt the symmetric key during key exchange because RSA is slow and limited to short data.
Hash algorithm : Produces a fixed‑length digest (e.g., SHA‑256). Any change in the input yields a completely different output.
Signature algorithm : Private‑key signs data; public‑key verifies the signature.
HTTPS Principle
HTTPS (Hypertext Transfer Protocol Secure) secures communication by layering SSL/TLS encryption over HTTP, using X.509 certificates for identity verification and ensuring confidentiality and integrity of transmitted data.
WeChat Pay Encryption
Request signature : Each request is signed with the merchant API certificate private key using RSA‑SHA256; WeChat Pay verifies the signature.
Callback verification : WeChat Pay signs callbacks with its platform private key; the merchant verifies using the platform public key.
Callback decryption : The merchant decrypts encrypted callback data with the configured apiV3 key using AES‑256‑GCM.
Interface Encryption Design
Key exchange : The client encrypts the symmetric key with the server’s public key and sends the ciphertext; the server decrypts it with its private key.
Data encryption : The client encrypts request data with the symmetric key; the server decrypts with the same key.
Data hashing (signature) : The client computes a hash of the data (including the plaintext symmetric key) and sends the hash as a signature; the server recomputes and compares to verify integrity.
Validity check : The client includes a timestamp; the server validates the timestamp to prevent replay attacks.
Technical Implementation
Key Generation & Management
Generate an RSA key pair with a tool. The server stores the private key securely. The client periodically fetches the server’s public key (e.g., via a secure endpoint) and caches it locally.
Algorithm Selection and Code Example
Symmetric algorithm: AES; Asymmetric algorithm: RSA; Hash algorithm: SHA‑256 (MD5 optional); Signature algorithm: RSA‑SHA256. The following Java snippet uses the Hutool library to illustrate the workflow.
// Symmetric key
String key = "key";
AES aes = SecureUtil.aes(key.getBytes());
// Encrypt data
String ciphertext = aes.encryptBase64(content);
// Decrypt data
String result = aes.decryptStr(ciphertext);
// RSA public key (server side)
String publicKey = "xxxxxxx";
RSA rsaPub = new RSA(null, publicKey);
// Encrypt symmetric key with public key
String encryptedKey = rsaPub.encryptBase64(key, KeyType.PublicKey);
// RSA private key (server side)
String privateKey = "xxxxxxx";
RSA rsaPriv = new RSA(privateKey, null);
// Decrypt symmetric key
String decryptedKey = rsaPriv.decryptStr(encryptedKey, KeyType.PrivateKey);
// SHA‑256 hash
Digester sha256 = new Digester(DigestAlgorithm.SHA256);
String hash = sha256.digestHex(data);
// RSA‑SHA256 signature
Sign signer = SecureUtil.sign(SignAlgorithm.SHA256withRSA, privateKey, null);
String sign = Base64.getEncoder().encodeToString(signer.sign(data));
Sign verifier = SecureUtil.sign(SignAlgorithm.SHA256withRSA, null, publicKey);
boolean ok = verifier.verify(data.getBytes(), Base64.getDecoder().decode(sign));Signature Construction
After encrypting queryString and body, concatenate queryString, the timestamp ( ts), the plaintext symmetric key, and the body in that order. Compute a SHA‑256 hash of the concatenated string; the resulting digest is the sign value placed in the request header.
Parameter Transmission
ek (encrypt‑key): RSA‑encrypted symmetric key.
ts : Unix timestamp.
sign : SHA‑256 signature as described above.
Example request format:
GET /api/resource?ciphertext=xxxxx HTTP/1.1
Header: ts=1691234567
Header: ek=xxxxx
Header: sign=abcdef123456...
Body: base64(ciphertext_of_body)Backend Processing Steps
Timestamp validation : Extract ts from the header and ensure it falls within an acceptable window (e.g., ±5 minutes).
Decrypt symmetric key : Use the server’s private RSA key to decrypt ek, obtaining the plaintext symmetric key.
Signature verification : Re‑assemble queryString, ts, the decrypted symmetric key, and body, hash with SHA‑256, and compare the result with the sign header.
Parameter decryption : Decrypt the encrypted queryString and body using the symmetric key (AES‑256‑GCM or AES‑CBC as configured).
Response encryption : Encrypt the response payload with the same symmetric key, encode the ciphertext in Base64, and return it to the client.
Security Analysis
The hybrid scheme leverages the speed of symmetric encryption for bulk data and the security of asymmetric encryption for key exchange, providing confidentiality, integrity, and acceptable performance. Key security considerations include:
Anti‑tampering : All request parameters are signed; without the client’s public key an attacker cannot modify them without detection.
Anti‑crawler : Encrypted and signed parameters prevent automated scraping; encrypted responses are unintelligible without the symmetric key.
Anti‑replay : The timestamp included in the signature prevents replay attacks; short‑term replay can be mitigated by server‑side caching if needed.
Client‑side public key protection : Use code obfuscation, avoid hard‑coding the key, store it in encrypted or split form, and rely on per‑request generation of a fresh symmetric key to limit the impact of key exposure.
Architect
Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
