Secure the restoring of Passwd in SourceCode | 换位思考重构架构,从源码上保护密码安全 | Java

in #cn6 years ago (edited)

前言 - Preface


IMG_2852.jpg

最近从 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.

Sort:  

这好专业啊。

外行看内行,不管什么行业,都是这样子的;做安全的朋友,看到我这代码,可能就要笑了

看不懂啊也支持!我老公也是编程的,我一心一意支持他的工作,虽然他时刻想着辞职。。。

羡慕你老公啊,还有私人的程序猿鼓励师

哈哈,不行我可以做你的私人鼓励师

俏咪咪的说:我有女朋友的啦

😳不觉明厉

我错了,以后写文一定简单易懂

你好cn区点赞机器人 @cnbuddy 很开心你能成为cn区的一员。倘若你想让我隐形,请回复“取消”。

感谢小 buddy 一直以来的支持!

给壮士送行!

你们一心想要赶走我

你想多了,你这是从我们村的小学毕业了。送你去上初中~

Congratulations @coder-bts! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

Award for the number of upvotes

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

Upvote this notification to help all Steemit users. Learn why here!

想法很棒,00后这样的思路,架构师很近了,未来的路无可限量

感谢鼓励!

辛苦你给我解释一堆,虽然我截屏了,本来准备今天好好看你帖子的,结果忙到现在,还有8页的东西(英语渣面对8页英文)等着我看明白了后修改~只能改天了~

没事慢慢来 :D

java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
byte[] array = md.digest(md5.getBytes());

这里是不是已经MD5了?
那下面这段我没理解~

for (int i = 0; i < array.length; ++i) {
    sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
}

因为要转成 String,所以比较复杂

既然是转成string,为什么要substring?我想知道下array 被赋值后的内容,你能随意输入个密码然后输入array的值给我看看帮助我理解下嘛?🧐

Coin Marketplace

STEEM 0.29
TRX 0.12
JST 0.033
BTC 62934.09
ETH 3118.65
USDT 1.00
SBD 3.85