大多数应用程序开发人员都会将一些第三方库集成到他们的应用程序中.如果它是为了访问服务,比如Dropbox或YouTube,或者是为了记录崩溃.第三方图书馆和服务的数量惊人.这些库和服务中的大多数都是通过某种方式与服务进行身份验证来集成的,大多数情况下,这是通过API密钥进行的.出于安全目的,服务通常生成公钥和私钥,通常也称为秘密密钥.不幸的是,为了连接到服务,此私钥必须用于身份验证,因此很可能是应用程序的一部分. 不用说,这面临着巨大的安全问题.公钥和私钥可以在几分钟内从APK中提取出来,并且可以很容易地实现自动化.

假设我有类似的东西,我如何保护密钥:

public class DropboxService  {

    private final static String APP_KEY = "jk433g34hg3";
    private final static String APP_SECRET = "987dwdqwdqw90";
    private final static AccessType ACCESS_TYPE = AccessType.DROPBOX;

    // SOME MORE CODE HERE

}

您认为存储私钥的最佳和最安全的方式是什么?迷惑,加密,你怎么看?

推荐答案

  1. 实际上,编译后的应用程序不仅包含密钥字符串,还包含常量名称APP_KEY和APP_SECRET.从这种self 记录的代码中提取密钥非常简单,例如使用标准的Android工具DX.

  2. 您可以应用ProGuard.它将保持键字符串不变,但会删除常量名称.它还将尽可能用短而无意义的名称来重命名类和方法.然后,提取密钥需要更多的时间,以确定哪个字符串用于哪个目的.

    Note that setting up ProGuard shouldn't be as difficult as you fear. To begin with, you only need to enable ProGuard, as documented in project.properties. If there are any problems with third-party libraries, you may need to suppress some warnings and/or prevent them from being obfuscated, in proguard-project.txt. For instance:

    -dontwarn com.dropbox.**
    -keep class com.dropbox.** { *; }
    

    This is a brute-force approach; you can refine such configuration once the processed application works.

  3. 您可以在代码中手动混淆字符串,例如,使用Base64编码,或者最好使用更复杂的编码;甚至可以使用本机代码.然后,黑客必须对您的编码进行静态反向工程,或者在适当的位置动态拦截解码.

  4. 您可以应用商业模糊器,比如ProGuard的专用sibling DexGuard.它还可以为您加密/模糊字符串和类.然后提取密钥需要更多的时间和专业知识.

  5. 您可以在自己的服务器上运行部分应用程序.如果你能把 keys 放在那里,它们就安全了.

最后,这是一个你必须做出的经济权衡: keys 有多重要,你能负担多少时间或软件,对 keys 感兴趣的黑客有多老练,他们想花多少时间, keys 被破解前的延迟值多少,成功的黑客会以多大的规模分发密钥等.密钥之类的小块信息比整个应用程序更难保护.从本质上讲,客户端没有什么是牢不可破的,但你当然可以提高标准.

(我是ProGuard和DexGuard的开发者)

Android相关问答推荐

将动作传递给嵌套的可组合物

如何在Android Emulator上从物理设备接收TCP消息

如何从Android 12的来电中获取电话号码?

如何在Jetpack Compose中更新异步回调的用户界面

Android-LVL库始终返回NOT_SUBLISTED

如何在使用带有底部导航组件的片段管理器时更改片段工具栏的标签

为什么Kotlin允许将非空值类型化为可空类型,但又将其视为非空值?

Kotlin为多个控件设置一个侦听器

Hilt+Worker NoSuchMethodException:<;init>;[class android.content.Context,class androidx.work.WorkerParameters]

未解析的引用:视图模型

android crashlytics 显示崩溃但不显示我的课程中的位置

制作圆形SupportMapFragment

Spinner - onItemLongClick 从未执行

视觉转换后获取文本

在 Jetpack Compose 中自动滚动后面的项目

如何在组件之间导航

Jetpack Compose TextField 在输入新字符时不更新

如何对齐文本和图标可组合,以便即使在文本溢出后它们也能保持在一起?

运行一次 kotlin 流,但在下游收到两次

当我更改 ViewModel var 时,Kotlin + Compose 中的 Composable 不会更新