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

PostgreSQL结合Android应用的客户端加密实现方案咨询(学校项目)

客户端加密实现思路与分步指南

先给你理清整个架构下的加密逻辑:咱们要做的是端到端的敏感数据加密——从Android客户端本地就把敏感数据加密,通过HTTPS(已经解决传输加密)传到PHP服务,PHP再把密文原封不动(或按需做数据库层二次加密)存到PostgreSQL,全程只有Android客户端持有解密密钥,这样哪怕服务器或数据库被攻破,数据也不会泄露。同时还要确保PHP和PostgreSQL的连接也是加密的,补上链路最后一环。

一、核心实现思路拆解

  • 客户端本地加密:敏感数据在Android设备上完成加密,密钥由Android系统的KeyStore托管,绝不硬编码或明文传输密钥。
  • 传输加密复用HTTPS:你已经用了HTTPS,这一步不用额外改动,它能保障客户端到Apache/PHP的传输安全。
  • PHP-PostgreSQL加密连接:配置PHP的PostgreSQL连接为SSL加密模式,避免中间链路窃听。
  • 数据库端可选增强加密:用PostgreSQL的pgcrypto扩展对存储的密文做二次加密(或对非客户端加密的字段加密),双重保障。

二、具体分步实现

1. Android客户端侧:敏感数据加密与密钥管理

这是客户端加密的核心,重点是安全管理密钥和选用合规加密算法:

  • 用Android KeyStore生成并存储AES-256-GCM密钥(推荐GCM模式,自带完整性校验):
    // 生成密钥示例(Kotlin)
    val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
    val keyGenParameterSpec = KeyGenParameterSpec.Builder(
        "my_app_encryption_key",
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
    )
        .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
        .setKeySize(256)
        .build()
    keyGenerator.init(keyGenParameterSpec)
    val secretKey = keyGenerator.generateKey()
    
  • 加密敏感数据(比如用户手机号、身份证号):
    fun encryptData(plaintext: String, secretKey: SecretKey): ByteArray {
        val cipher = Cipher.getInstance("AES/GCM/NoPadding")
        cipher.init(Cipher.ENCRYPT_MODE, secretKey)
        val iv = cipher.iv // 要和密文一起传到服务器,解密需要用
        val encryptedData = cipher.doFinal(plaintext.toByteArray(Charsets.UTF_8))
        // 把IV和密文拼接(IV在前,方便解密时拆分)
        return iv + encryptedData
    }
    
  • 解密时从服务器拿到拼接的字节数组,拆分IV和密文再解密即可。

2. PHP侧:加密连接PostgreSQL + 透传密文

首先确保你的PHP环境支持PostgreSQL扩展(一般Apache+PHP都自带,没装的话装php-pgsql):

  • 用PDO建立SSL加密连接(免费PostgreSQL服务默认都支持SSL):
    $host = "your-free-pg-host";
    $dbname = "your-db-name";
    $user = "db-user";
    $password = "db-password";
    // 强制SSL连接,sslmode=require表示必须加密连接
    $dsn = "pgsql:host=$host;port=5432;dbname=$dbname;sslmode=require";
    try {
        $pdo = new PDO($dsn, $user, $password);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch(PDOException $e) {
        die("Connection failed: " . $e->getMessage());
    }
    
  • 接收Android传来的加密数据(IV+密文),直接存到PostgreSQL的bytea类型字段里,不需要解密:
    // 假设POST请求里的encrypted_data是Base64编码的字节数组
    $encryptedData = base64_decode($_POST['encrypted_data']);
    $stmt = $pdo->prepare("INSERT INTO user_data (sensitive_info) VALUES (?)");
    $stmt->bindParam(1, $encryptedData, PDO::PARAM_LOB);
    $stmt->execute();
    

3. PostgreSQL端:可选增强加密(pgcrypto扩展)

如果需要对某些非客户端加密的字段(比如PHP生成的日志数据)加密,或者给已存的密文再加一层保护,可以启用PostgreSQL的pgcrypto扩展:

  • 先启用扩展(免费PostgreSQL服务一般允许创建扩展):
    CREATE EXTENSION IF NOT EXISTS pgcrypto;
    
  • 用pgcrypto的encrypt函数加密字段(注意这里的密钥要存在PHP的安全配置里,不要硬编码):
    -- 插入时加密示例
    INSERT INTO logs (content) VALUES (encrypt('plaintext_log', 'your_db_encryption_key', 'aes-gcm'));
    -- 查询时解密
    SELECT decrypt(content, 'your_db_encryption_key', 'aes-gcm') FROM logs;
    

注意:如果是客户端已经加密的数据,不需要在数据库端再解密,直接存密文即可,这一步是额外的安全增强。

4. 免费PostgreSQL服务选型(适合学校项目)

给你推荐几个靠谱的免费选项:

  • Supabase:免费层有500MB存储、1GB带宽,自带可视化管理界面,支持SSL连接,适合快速搭建。
  • Neon:免费层有1GB存储、无带宽限制,支持serverless架构,适合轻量项目。
  • Heroku Postgres:免费层有10000行限制,会自动休眠(7天不访问),适合测试用。
  • AWS RDS Free Tier:12个月免费,有20GB存储,适合长期的学校项目(需要AWS账号)。

三、关键注意事项

  • 绝对不要把客户端解密密钥传到服务器或存在代码仓库里,完全由Android KeyStore托管。
  • 加密算法一定要选安全的:优先AES-256-GCM,避免用ECB模式或弱加密算法。
  • 测试加密解密流程:确保加密后的数据能正常解密,避免出现数据损坏。
  • 定期轮换密钥:如果需要,可以实现客户端密钥轮换机制,避免长期使用同一密钥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:27:29