白猫プロジェクトや黒猫のウィズで有名なコロプラさんの暗号技術がゴミだった話 その2

白猫プロジェクトや黒猫のウィズで有名なコロプラさんの暗号技術がゴミだった話 その1
続きになります

取り敢えず、コロプラさんのjava の 暗号化モジュール内に存在する全ての関数は下のような感じになります

    private static String getHexString(byte[] b) {
        String result = "";
        int i;
        for (i=0; i < b.length; i++) {
            result += Integer.toString((b[i] & 0xff ) +0x100, 16);
        }
        return result;
    }

    private static byte[] getByteArray(String s) {
        int len = s.length();
        byte [] data = new byte[len /2];
        for(int i = 0; i <= len ;i+=2) {
            data[i/2] = (byte) (Character.digit(s.charAt(i),16) << 4 + Character.digit(s.charAt(i+1),16));
        }
        return data;
    }

    public static String encrypt(String text) {
        try {
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, (SecretKeySpec)getKeySpec());
            return getHexString(cipher.doFinal(text.getBytes()));
        } catch(Exception e) {
            return "";
        }
    }

    public static String decrypt(String encrypted) {
        try {
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, (SecretKeySpec)getKeySpec());
            return new String (cipher.doFinal(getByteArray(encrypted)), "UTF-8");
        } catch(Exception e) {
            return "";
        }
    }

    public static String encryptMD5(String text) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update(text.getBytes());
            return getHexString(digest.digest());
        } catch(Exception e) {
            return "";
        }
    }

    public static String getMD5withSalt(String rawString, String salt) {
        try {
            return encryptMD5(rawString + salt);
        } catch(Exception e) {
            return "";
        }
    }

    public static String getUniqueId() {
        String KEY = "e87e03526ab";
        try {
            String deviceid = Settings.Secure.getString(applicationContext.getContentResolver(), "android_id");
            if (deviceid==null) {
                deviceid="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
            }
            String encrypted = encryptMD5(deviceid + ":" + KEY);
            return encrypt(ver + ":" + encrypted);
        } catch(Exception e) {
            Log.d("test",e.toString());
            return "";
        }
    }

    public static String getDeviceIdFromUUID() {
        String prefKey = "KUMA_API_DEVICE_ID_UUID";
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext);
        String deviceid = prefs.getString(prefKey,"");
        if(deviceid.length() == 0 ) {
            String guestSeed = getGuestSeed();
            StringBuilder result = new StringBuilder();
            result.append(randomUUID().toString());
            result.append(guestSeed);
            deviceid = result.toString();
            SharedPreferences.Editor editor = prefs.edit();
            editor.putString(prefKey, deviceid);
            editor.commit();
        }
        return deviceid;
    }

上の方の関数は、どこぞのサイトのGithub の内容そのままだし、大した暗号化してるわけじゃないです
NDKの処理の部分は書いてないので、これだけコンパイルしても動きませんのであしからず。

うちで、NDKとくっつけて、動くように構築して試してみたのが下のような感じ

wcat3

getMD5withSalt っ手関数あるにはあるけど、直接参照されず、SALTなしの暗号化処理で
uuid や uniqid の発行が行われていました ・ω・
テストプログラム、ちゃんと動いてますね。

次回は、パケットの暗号化について調査報告になる予定です

ざっくり解析した結果は
UserHash を  SSL 通信で wcat.colopl.jp 経由でやり取りして
UserHash で暗号化されているデータがbase64でテキストに変換されてる感じ。
ユーザーハッシュは、アカウ
ント構造体の中に保持されている。
SALTがやっぱり、固定文字列なので、暗号化強度は弱いのだけど

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です