前言 - Preface
最近从 0 到 1,在写一个紧急响应 CMDLine 程序,暂时命名为 Epic Party Protocol,有兴趣的朋友可以猜测一下命名,灵感来源,提示一下,是两部电影。
I am recently starting a program from scratch, named "Epic Party Protocol" for now. You can guess where I get the idea for this name if interested. (Hint: from 2 different movies)
在写其中一个密码验证的部分的时候,我是打算把密码之前存储在源码内的,但是突然觉得不安全,如果通过某种方式让其他人拿到源码,密码就暴露了。
When I am writing the passwd auth part, I was going to put the passwd right into the sourcecode. Then I realized if someone somehow sees my sourcecode, everything leaks out.
于是,我开始了一种新的思考
So I started a new idea.
源码角度保护密码
做安全的朋友,抱歉,见笑了,我没有什么做安全的经验,所以这种事情对我来说也是非常新的事情,考虑可能有所不周,可能看起来比较弱智 😅
For friends who works in sec field, sorry, this might be a dumb idea. I am not familiar to sec and this is very new for me.
密码明文存储在源码中是不安全的,于是我想到了一种方法:我能不能把密码加密,把密文放进去,然后把用户输入的密码也加密,对比密文是否相符。
Direct text is not safe, but what if I can encode the passwd somehow, and put it in the code, and then encode the passwd that the user types in. See if it matches.
加密算法,不可逆,我第一时间想到了:MD5
None reversible encrypting algorithm? Yes, MD5.
源码 - Code
因为某种原因,Steemit 不支持代码高亮,点击这里 查看高亮代码。
For some reason, Steemit does not support syntax highlight, click here to view highlight.
import java.util.*; //All u need for now
import java.security.*; //For encrypting
import java.io.*; //i know u may don't believe this but this is for passwd typing sec
public class Epic
{
//Rock && Roll!!!
private static String passwd_salt_asdf; //encrypt it later, salt for idk reason
public static void main(String []args)
{
Scanner input = new Scanner(System.in); //Initializing Scanner
Console cons=System.console(); //For the sake of sec, stop using Scanner!!!
lockup(); //Sec
System.out.println("");
//System.out.println("See U Soon Sir..."); //Keep this for now
System.out.print("P-Project Private Key: ");
String input_passwd = new String(cons.readPassword());
//System.out.println(MD5(input_passwd));
//System.out.println(input_passwd);
if(!auth_md5(input_passwd))
{
System.out.println(">>> ACCESS DENIED <<<\n");
System.exit(0);
}
//
//For Sec Reason
System.out.println(">>> ACCESS GRANTED <<<");
System.out.println();
welcome();
System.out.println();
System.out.println();
}
public static void lockup() //Correct Passwd
{
passwd_salt_asdf = "0ba1e9d7c125978af4d0402c56753f1b";
}
public static String MD5(String md5) { //For MD5
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
byte[] array = md.digest(md5.getBytes());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < array.length; ++i) {
sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
}
return sb.toString();
} catch (java.security.NoSuchAlgorithmException e) {
}
return null;
}
public static boolean auth_md5(String key) //Check Passwd
{
String decode_input = MD5(key);
if(decode_input.equals(passwd_salt_asdf))
return true;
return false;
}
public static void welcome()
{
System.out.println("m m \"\"# mmmm \" ");
System.out.println("# # # mmm # mmm mmm mmmmm mmm #\" \" mmm m mm ");
System.out.println("\" #\"# # #\" # # #\" \" #\" \"# # # # #\" # \"#mmm # #\" \"");
System.out.println(" ## ##\" #\"\"\"\" # # # # # # # #\"\"\"\" \"# # # ");
System.out.println(" # # \"#mm\" \"mm \"#mm\" \"#m#\" # # # \"#mm\" \"mmm#\" mm#mm # ");
}
}
代码分析 - Analysis
一大坨代码放上来肯定会晕,我慢慢分析一下。
A pile of code together is hard to read, let's break it down.
首先会有一个 bash 脚本作为启动器来加载这个用 Java 写的主程序,然后 Java 中,用到的库:
Library imported for Scanner, MD5 and console function.
import java.util.*; //为了使用 Scanner(System.in)
import java.security.*; //为了使用 MD5 加密
import java.io.*; //为了 Console 安全读取密码
密码存储在:
Passwd saved:
public static void lockup() //Correct Passwd
{
passwd_salt_asdf = "0ba1e9d7c125978af4d0402c56753f1b";
}
用的是一个 Private 全局变量,后面那串 salt 之类的只是干扰作用,这是通过 MD5 加密的密码,然后有了:
This is a private var, the salt is just for distraction. This is a passwd through md5, and then:
public static String MD5(String md5) { //For MD5
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
byte[] array = md.digest(md5.getBytes());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < array.length; ++i) {
sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
}
return sb.toString();
} catch (java.security.NoSuchAlgorithmException e) {
}
return null;
}
调用了库 security 中的 MessageDigest,最后比对密文是否一样。
Used MessageDigest from security library, see if it matches.
最后其实还有个小细节:
One more thing here:
String input_passwd = new String(cons.readPassword());
利用 console 来读取密码,使密码输入时不会显示。
Use console to hide passwd when typing.
这样一来,就写出了严谨安全的程序。
There we go, secured program.
结语 - Conclusion
这其实就是一种思路,问题还是很大的,再怎么说也要 MD5 两次才足够安全。
It is just an idea, still a lot of problems here. We need at least encrypt it twice.
当然,做安全的朋友们,就当是看笑话了。
Well, sec guys, this may be just a fun story for yall.