How to Secure Public APIs: Signatures, OAuth2, and Encryption Strategies

This article explains practical methods to protect externally exposed APIs, covering token‑based access, OAuth2.0 authorization, signature verification, encryption techniques (hashing, symmetric and asymmetric), key management, and provides Java code samples for DES and RSA implementations.

21CTO
21CTO
21CTO
How to Secure Public APIs: Signatures, OAuth2, and Encryption Strategies

1. Token‑Based API Platform

Third‑party institutions apply for an appId and obtain an accessToken. Each request deletes the old token and stores the new one (commonly in Redis with expiration). The token is sent as a request parameter; the server checks its existence in the persistent layer to verify the institution’s legitimacy.

2. OAuth2.0 Authentication

Third‑party authorization follows a similar principle to the token method. The service provider (A) offers an API; an external party (B) must register its own appId. When B needs to access A’s API, it obtains user consent, A generates an authorization token for B, and B uses the token to request resources.

Overall flow:

User consents and obtains a code.

Exchange the code for a web‑authorization access_token.

Use access_token to retrieve the user’s openId.

Use openId to fetch user information.

3. Encryption and Key Management

Key techniques include:

One‑way hash (MD5, SHA‑1) for data integrity and tamper detection.

Symmetric encryption (e.g., DES) for high‑performance confidentiality of large data.

Asymmetric encryption (RSA) using a public key for encryption and a private key for decryption, suitable for secure key exchange and financial/payments scenarios.

Hash functions produce fixed‑length, irreversible digests; a small change in input causes a large change in output (avalanche effect). Symmetric algorithms use the same secret key for encryption and decryption, offering fast processing but requiring secure key distribution. Asymmetric algorithms use a key pair, providing stronger security at the cost of slower performance.

4. Code Examples

Java implementations for DES encryption/decryption:

public class DES {
    public static byte[] encrypt(byte[] datasource, String password) {
        try {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(password.getBytes());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey securekey = keyFactory.generateSecret(desKey);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
            return cipher.doFinal(datasource);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }
    public static byte[] decrypt(byte[] src, String password) throws Exception {
        SecureRandom random = new SecureRandom();
        DESKeySpec desKey = new DESKeySpec(password.getBytes());
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(desKey);
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.DECRYPT_MODE, securekey, random);
        return cipher.doFinal(src);
    }
    public static void main(String[] args) throws Exception {
        String str = "123456";
        String password = "12345678";
        byte[] encrypt = encrypt(str.getBytes(), password);
        System.out.println("加密前:" + str);
        System.out.println("加密后:" + new String(encrypt));
        byte[] decrypt = decrypt(encrypt, password);
        System.out.println("解密后:" + new String(decrypt));
    }
}

Java implementation for RSA key generation, encryption, and decryption:

public class RSAUtil {
    public static String publicKey;
    public static String privateKey;
    public static void generateKey() {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            SecureRandom sr = new SecureRandom();
            keyPairGenerator.initialize(512, sr);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            publicKey = Base64.encodeBase64String(((RSAPublicKey) keyPair.getPublic()).getEncoded());
            privateKey = Base64.encodeBase64String(((RSAPrivateKey) keyPair.getPrivate()).getEncoded());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
    public static String encryptByprivateKey(String content, String privateKeyStr, int opmode) {
        try {
            PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr));
            KeyFactory kf = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = kf.generatePrivate(pkcs8);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(opmode, privateKey);
            if (opmode == Cipher.ENCRYPT_MODE) {
                return Base64.encodeBase64String(cipher.doFinal(content.getBytes()));
            } else if (opmode == Cipher.DECRYPT_MODE) {
                return new String(cipher.doFinal(Base64.decodeBase64(content)), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static String encryptByPublicKey(String content, String publicKeyStr, int opmode) {
        try {
            X509EncodedKeySpec x509 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
            KeyFactory kf = KeyFactory.getInstance("RSA");
            PublicKey publicKey = kf.generatePublic(x509);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(opmode, publicKey);
            if (opmode == Cipher.ENCRYPT_MODE) {
                return Base64.encodeBase64String(cipher.doFinal(content.getBytes()));
            } else if (opmode == Cipher.DECRYPT_MODE) {
                return new String(cipher.doFinal(Base64.decodeBase64(content)), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static void main(String[] args) throws Exception {
        generateKey();
        System.out.println("Public Key:" + publicKey);
        System.out.println("Private Key:" + privateKey);
        // Private key encrypt, public key decrypt
        String text = "11111111";
        String cipherText = encryptByprivateKey(text, privateKey, Cipher.ENCRYPT_MODE);
        System.out.println("Private encrypt:" + cipherText);
        System.out.println("Public decrypt:" + encryptByPublicKey(cipherText, publicKey, Cipher.DECRYPT_MODE));
        // Public key encrypt, private key decrypt
        String text2 = "222222";
        String cipherText2 = encryptByPublicKey(text2, publicKey, Cipher.ENCRYPT_MODE);
        System.out.println("Public encrypt:" + cipherText2);
        System.out.println("Private decrypt:" + encryptByprivateKey(cipherText2, privateKey, Cipher.DECRYPT_MODE));
    }
}

5. Signature Verification

Client sends business parameters together with a signature calculated as md5(business_parameters). The server recomputes the MD5 of the received parameters and compares it with the provided signature to ensure data integrity.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaencryptionOAuth2API Securitycryptography
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.