【发布时间】:2019-07-25 12:53:16
【问题描述】:
我有一个 android 应用程序,它有支付网关和另一个服务。我使用 AES 模型来加密和解密应用程序和服务器之间的数据。我使用存储在 android 类中的 KEY 和 IV 常量。我的问题是如何在 android 应用程序中加密这些常量(IV 和 Key),以防止任何攻击者对 APK 文件进行反编译并显示这些常量。
【问题讨论】:
标签: android .net encryption aes
我有一个 android 应用程序,它有支付网关和另一个服务。我使用 AES 模型来加密和解密应用程序和服务器之间的数据。我使用存储在 android 类中的 KEY 和 IV 常量。我的问题是如何在 android 应用程序中加密这些常量(IV 和 Key),以防止任何攻击者对 APK 文件进行反编译并显示这些常量。
【问题讨论】:
标签: android .net encryption aes
您必须使用 RSA 公钥加密密钥,并且只有服务器知道此公钥的私钥并可以对其进行解密。
您使用服务器端的私钥解密 AES 密钥,并使用解密后的 AES 密钥解密您的原始消息。
//编辑
这是 Android Studio 中的 Java 代码示例。我的 RSA 公钥存储在共享首选项中。
安装应用程序后,它会调用服务器,在服务器上生成 RSA 密钥对,两个密钥都保存在数据库中,公钥发送到设备并保存在共享首选项中。每当需要加密时,都会创建存储的公钥并用于加密,只有服务器知道私钥。
byte[] ENCRYPTED_AES_KEY_IN_BYTE = null;
String ENCRYPTED_AES_KEY;
cipher = null;
cipher = Cipher.getInstance("RSA/NONE/OAEPwithSHA-1andMGF1Padding");
// Get the shared preferences where the public key is stored
// SharedPreferences preferences = getApplicationContext().getSharedPreferences(preferences,Context.MODE_PRIVATE);
// get the Publickey stored as string in the shared preferences
String stringkey = preferences.getString(PUBLICKEY,"");
// create a public RSA Key from the stored key
X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(stringkey,Base64.DEFAULT));
KeyFactory keyFactory;
PublicKey key =null;
keyFactory = KeyFactory.getInstance("RSA");
key = keyFactory.generatePublic(spec);
//Encrypt the AES key with the RSA public key
cipher.init(Cipher.ENCRYPT_MODE, key);
ENCRYPTED_AES_KEY_IN_BYTES = AES_KEY.getEncoded();
ENCRYPTED_AES_KEY_IN_BYTE = cipher.doFinal(ENCRYPTED_AES_KEY_IN_BYTE);
ENCRYPTED_AES_KEY = Base64.encodeToString(ENCRYPTED_AES_KEY_IN_BYTE,Base64.DEFAULT);
//ENCRYPTED_AES_KEY is now the Encrypted AES Key as string
// 编辑#2
在服务器上创建一个 RSA KEY 对
$rsa = new Crypt_RSA();
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS8);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS8);
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
extract($rsa->createKey());
$publickey = str_replace("-----BEGIN PUBLIC KEY-----\r\n","",$publickey);
$publickey = str_replace("-----END PUBLIC KEY-----","",$publickey);
$privatekey = str_replace("-----BEGIN PRIVATE KEY-----\r\n","",$privatekey);
$privatekey = str_replace( "-----END PRIVATE KEY-----","",$privatekey);
私钥保存到数据库,公钥发送给客户端加密数据。
再次解密服务器端的数据
$rsa = new Crypt_RSA();
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS8);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS8);
$rsa->setEncryptionMode( CRYPT_RSA_ENCRYPTION_OAEP);
$IV = base64_decode($IV);
$AESkey = base64_decode($AESkey);
$rsa->loadKey($privatekey);
$AESkey = $rsa->decrypt($AESkey);
// replace empty spaces with a + , this is something which can happen when you use a http request
$encrypteddata = str_replace(" ", "+", $encrypteddata);
$encrypteddata = base64_decode($encrypteddata);
$method = "AES-256-CBC";
$decrypteddata = openssl_decrypt($encrypteddata, $method, $AESkey, OPENSSL_RAW_DATA,$IV);
在此代码中不包括如何将私钥存储在数据库中以及如何从数据库中取回它。
【讨论】: