com.github.dactiv.fear.commons.AuthCoder.java Source code

Java tutorial

Introduction

Here is the source code for com.github.dactiv.fear.commons.AuthCoder.java

Source

/*
 * Copyright 2015 dactiv
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.dactiv.fear.commons;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * Java  Discuz!  iv 
 *
 * @author maurice
 */
public class AuthCoder {

    /**
     * ?
     */
    public final static int DEFAULT_RANDOM_KEY_LENGTH = 4;
    /**
     * ?
     */
    public final static String DEFAULT_VALUE_ENCODING = "UTF-8";
    /**
     * ?
     */
    public final static int DEFAULT_EXPIRY = 0;

    /**
     * 
     *
     * @param value ?
     * @param key   
     * @return ?
     * @throws UnsupportedEncodingException
     */
    public static String decode(String value, String key) throws UnsupportedEncodingException {
        return decode(value, key, DEFAULT_RANDOM_KEY_LENGTH);
    }

    /**
     *
     * @param value           ?
     * @param key             
     * @param randomKeyLength ? ? 0-32????
     *                        ???iv??
     *                        ? = 16  randomKeyLength  0 ??
     * @return ?
     * @throws UnsupportedEncodingException
     */
    public static String decode(String value, String key, int randomKeyLength) throws UnsupportedEncodingException {
        return decode(value, key, randomKeyLength, DEFAULT_VALUE_ENCODING);
    }

    /**
     * 
     * @param value    ?
     * @param key      
     * @param encoding ?
     * @return ?
     * @throws UnsupportedEncodingException
     */
    public static String decode(String value, String key, String encoding) throws UnsupportedEncodingException {
        return decode(value, key, DEFAULT_RANDOM_KEY_LENGTH, encoding);
    }

    /**
     * 
     *
     * @param value           ?
     * @param key             
     * @param randomKeyLength ? ? 0-32????
     *                        ???iv??
     *                        ? = 16  randomKeyLength  0 ??
     * @param encoding        ?
     * @return ?
     */
    public static String decode(String value, String key, int randomKeyLength, String encoding)
            throws UnsupportedEncodingException {

        key = DigestUtils.md5Hex(key.getBytes());

        String keya = DigestUtils.md5Hex(StringUtils.substring(key, 0, 16).getBytes());
        String keyb = DigestUtils.md5Hex(StringUtils.substring(key, 16, 16 + 16).getBytes());
        String keyc = randomKeyLength > 0 ? StringUtils.substring(value, 0, randomKeyLength) : "";

        String cryptKey = keya + DigestUtils.md5Hex((keya + keyc).getBytes());
        int cryptKeyLen = cryptKey.length();

        value = new String(Base64.decodeBase64((StringUtils.substring(value, randomKeyLength))), encoding);
        int stringLen = value.length();

        List<Integer> rndKey = new ArrayList<>();

        StringBuilder result = new StringBuilder();

        Integer[] box = new Integer[256];
        for (int i = 0; i < box.length; i++) {
            box[i] = i;
        }

        for (int i = 0; i <= 255; i++) {
            rndKey.add((int) cryptKey.charAt(i % cryptKeyLen));
        }

        for (int j = 0, i = 0; i < 256; i++) {
            j = (j + box[i] + rndKey.get(i)) % 256;
            int tmp = box[i];
            box[i] = box[j];
            box[j] = tmp;
        }

        for (int k = 0, j = 0, i = 0; i < stringLen; i++) {
            k = (k + 1) % 256;
            j = (j + box[k]) % 256;
            int tmp = box[k];
            box[k] = box[j];
            box[j] = tmp;
            int a = (int) value.charAt(i);
            int b = box[(box[k] + box[j]) % 256];
            char r = (char) (a ^ b);
            result.append(r);
        }

        if ((NumberUtils.toInt(StringUtils.substring(result.toString(), 0, 10), -1) == 0
                || NumberUtils.toInt(StringUtils.substring(result.toString(), 0, 10), 0)
                        - System.currentTimeMillis() / 1000 > 0)
                && StringUtils.substring(result.toString(), 10, 10 + 16)
                        .equals(StringUtils.substring(
                                DigestUtils
                                        .md5Hex((StringUtils.substring(result.toString(), 26) + keyb).getBytes()),
                                0, 16))) {
            return StringUtils.substring(result.toString(), 26);
        } else {
            return "";
        }
    }

    /**
     * 
     *
     * @param value ?
     * @param key 
     * @return ?
     * @throws UnsupportedEncodingException
     */
    public static String encode(String value, String key) throws UnsupportedEncodingException {
        return encode(value, key, DEFAULT_EXPIRY);
    }

    /**
     * 
     *
     * @param value  ?
     * @param key    
     * @param expiry 
     * @return ?
     * @throws UnsupportedEncodingException
     */
    public static String encode(String value, String key, int expiry) throws UnsupportedEncodingException {
        return encode(value, key, expiry, DEFAULT_RANDOM_KEY_LENGTH, DEFAULT_VALUE_ENCODING);
    }

    /**
     * 
     *
     * @param value           ?
     * @param key             
     * @param expiry          
     * @param randomKeyLength ? ? 0-32????
     *                        ???iv??
     *                        ? = 16  randomKeyLength  0 ??
     * @return ?
     * @throws UnsupportedEncodingException
     */
    public static String encode(String value, String key, int expiry, int randomKeyLength)
            throws UnsupportedEncodingException {
        return encode(value, key, expiry, randomKeyLength, DEFAULT_VALUE_ENCODING);
    }

    /**
     * 
     * @param value    ?
     * @param key      
     * @param expiry   
     * @param encoding ?
     *
     * @return ?
     * @throws UnsupportedEncodingException
     */
    public static String encode(String value, String key, int expiry, String encoding)
            throws UnsupportedEncodingException {
        return encode(value, key, expiry, DEFAULT_RANDOM_KEY_LENGTH, encoding);
    }

    /**
     * 
     *
     * @param value           ?
     * @param key             
     * @param expiry          
     * @param randomKeyLength ? ? 0-32????
     *                        ???iv??
     *                        ? = 16  randomKeyLength  0 ??
     * @param encoding        ?
     * @return ?
     * @throws UnsupportedEncodingException
     */
    public static String encode(String value, String key, int expiry, int randomKeyLength, String encoding)
            throws UnsupportedEncodingException {

        key = DigestUtils.md5Hex(key.getBytes());
        String keya = DigestUtils.md5Hex(StringUtils.substring(key, 0, 16).getBytes());
        String keyb = DigestUtils.md5Hex(StringUtils.substring(key, 16, 16 + 16).getBytes());
        String keyc = randomKeyLength > 0 ? StringUtils.substring(
                DigestUtils.md5Hex(String.valueOf(System.currentTimeMillis() / 1000).getBytes()), -randomKeyLength)
                : "";

        String cryptKey = keya + DigestUtils.md5Hex((keya + keyc).getBytes());
        int cryptKeyLen = cryptKey.length();

        value = String.format("%010d", expiry > 0 ? expiry + System.currentTimeMillis() / 1000 : 0)
                + StringUtils.substring(DigestUtils.md5Hex((value + keyb).getBytes()), 0, 16) + value;
        int stringLen = value.length();

        List<Integer> rndKey = new ArrayList<>();
        StringBuilder result = new StringBuilder();
        Integer[] box = new Integer[256];
        for (int i = 0; i < box.length; i++) {
            box[i] = i;
        }

        for (int i = 0; i <= 255; i++) {
            rndKey.add((int) cryptKey.charAt(i % cryptKeyLen));
        }

        for (int j = 0, i = 0; i < 256; i++) {
            j = (j + box[i] + rndKey.get(i)) % 256;
            int tmp = box[i];
            box[i] = box[j];
            box[j] = tmp;
        }

        for (int k = 0, j = 0, i = 0; i < stringLen; i++) {
            k = (k + 1) % 256;
            j = (j + box[k]) % 256;
            int tmp = box[k];
            box[k] = box[j];
            box[j] = tmp;
            int a = (int) value.charAt(i);
            int b = box[(box[k] + box[j]) % 256];
            char r = (char) (a ^ b);
            result.append(r);
        }

        return keyc + Base64.encodeBase64String(result.toString().getBytes(encoding)).replaceAll("=", "");
    }

}