Most secure way to load sensitive information into protocol buffers

时间:2016-07-11 22:40:38

标签: java security protocol-buffers

My application uses Google protocol buffers to send sensitive data between client and server instances. The network link is encrypted with SSL, so I'm not worried about eavesdroppers on the network. I am worried about the actual loading of sensitive data into the protobuf because of memory concerns explained in this SO question.

For example:

Login login = Login.newBuilder().setPassword(password)// problem
                                .build();

Is there no way to do this securely since protocol buffers are immutable?

1 个答案:

答案 0 :(得分:3)

Protobuf不提供使用char[]代替String的任何选项。相反,Protobuf消息被有意设计为完全不可变的,它提供了不同类型的安全性:您可以在程序的多个沙盒组件之间共享单个消息实例,而不必担心可能会修改数据以干扰另一个

在我个人看来,作为一名安全工程师 - 虽然其他人会不同意 - 你所链接的SO问题中描述的“安全性”是安全影院,实际上并不值得追求,原因如下:

  1. 如果攻击者可以读取您的进程内存,那么您已经输了。即使你在丢弃它之前覆盖了秘密的内存,如果攻击者在正确的时间读取你的内存,他们也会找到密码。但是,更糟糕的是,如果攻击者能够读取进程的内存,他们可能会比提取临时密码做得更糟糕:他们可能会提取长期存在的秘密(例如服务器的TLS私钥) ,覆盖部分内存以更改应用程序的行为,访问您的应用程序可以访问的任何和所有资源等。这不是一个可以通过在使用后将某些字段归零来有意义解决的问题。

  2. 实际上,有太多方法可以复制你的秘密,而你无法控制,使整个练习没有实际意义:

    • 即使你小心,垃圾收集者也可以在移动记忆的同时制作秘密的副本,从而破坏目的。为避免这种情况,您可能需要使用由非托管内存支持的ByteBuffer
    • 当您将数据读入流程时,它几乎肯定会通过不以这种方式覆盖其数据的库代码。例如,InputStream可以执行内部缓冲,之后可能不会将其缓冲区清零。
    • 操作系统可以随时将您的数据分页到磁盘上的交换空间,之后没有义务将数据归零。因此,即使您将内存清零,它也可能会在交换中持续存在。 (加密交换可确保在系统关闭时有效地消除这些机密,但不一定能防止本地计算机上存在的攻击者能够从内核中提取交换加密密钥。)
  3. 所以,在我看来,在Java中使用可变对象特别是能够以这种方式覆盖秘密并不是一个有用的策略。这些威胁需要在其他地方解决。