英文:
How to hide a value in a compiled binary
问题
我想隐藏代码中的一个字符串常量。例如,在以下代码中,变量a
的值可以是一个秘密:
package main
import "fmt"
func main() {
a := "someStringXYZ"
fmt.Println(a)
}
这是如何编译这个go文件的:
$ go build -ldflags='-extldflags=-static' abc.go
同样也可以正常工作:
$ ./abc
someStringXYZ
如果我在这个二进制文件上使用strings
命令,我可以获取变量a
的值。
$ strings abc | grep XYZ
eq=runtime: val=someStringXYZsrmount errortimer expiredtraceStackTabtriggerRatio=value method xadd64 failedxchg64 failed}
有没有办法可以保持这个值的隐藏?
我不希望使用AppTokens从秘密存储中获取值的解决方案,因为这样AppTokens就会变得可见。
英文:
I want to hide a string constant present in the code. For example, in the following code - the variable a
's value can be a secret:
package main
import "fmt"
func main() {
a := "someStringXYZ"
fmt.Println(a)
}
This is how compiled this go file:
$ go build -ldflags='-extldflags=-static' abc.go
Works fine as well:
$ ./abc
someStringXYZ
If I use the strings
command on this binary then I can get the value of the variable a
.
$ strings abc | grep XYZ
eq=runtime: val=someStringXYZsrmount errortimer expiredtraceStackTabtriggerRatio=value method xadd64 failedxchg64 failed}
Is there a way I can keep this value hidden?
I'm not looking for a solution in which the app will use the AppTokens to get the value from secret storage because then the AppTokens becomes visible.
答案1
得分: 4
正如评论中所指出的,你无法完全隐藏它。为了至少从strings
中隐藏它(如果这是你想要的),你可以将它保存为[]byte
而不是string
,像这样:
package main
import "fmt"
func main() {
a := []byte("someStringXYZ")
fmt.Println(string(a))
}
现在,当我编译并在其上运行strings
时,它不再找到"someStringXYZ"。显然,如果你尝试,你仍然可以轻松提取它,并且它显然会在运行时的某个时刻显示在内存中,但这可能不是你目前关注的问题(我不确定你的应用程序是什么)。
请注意,这仅在字面量仅出现在转换中的情况下有效,而不是在其他任何地方。
无论如何,如果你有一个硬编码的令牌,并且需要隐藏它,那么在设计阶段你可能做错了一些事情。你应该重新考虑设计。
编辑:解释为什么这种方法有效;我不确定,但我认为这是因为[]byte
不会存储终止的空字节,或者类似的情况。strings
只会找到以某个不可打印字符结尾的长度为4或更长的可打印字符,所以实际上,我们可能只是侥幸而已。正如我之前所说,换个说法;混淆并不等于安全。如果someStringXYZ很重要,那么这种方法并不安全。
英文:
As the comments noted, you can't really make it fully hidden. What you can do, in order to at least hide it from strings
(if that's all you want), is save it as a []byte
, not a string
, like so:
package main
import "fmt"
func main() {
a := []byte("someStringXYZ")
fmt.Println(string(a))
}
Now, when I compile and run strings
on it, it doesn't find "someStringXYZ" anymore. You can still obviously extract it easily, if you tried, and it will obviously show up in memory at some point when it runs, but that might not be your immediate concern (I'm not sure what your application is).
Note that this only works if the literal only appears there in the cast, not anywhere else.
Either way - if you have a token hardcoded, and you need to hide it, you're probably doing something wrong at the design-stage. You should reconsider that design.
Edit: To explain why this method works; I'm not sure, but I think it's because []byte are not stored with a terminating null-byte, or something along those lines. strings
only finds printable characters of length 4 or longer that end with some unprintable character - so really, we might just be getting lucky. As I said before, but to phrase it differently; Obfuscation is not security. This isn't safe if someStringXYZ is important.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论