cc.agentx.security.BlowfishCipher.java Source code

Java tutorial

Introduction

Here is the source code for cc.agentx.security.BlowfishCipher.java

Source

/*
 * Copyright 2017 ZhangJiupeng
 *
 * 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 cc.agentx.security;

import cc.agentx.util.KeyHelper;
import org.bouncycastle.crypto.StreamBlockCipher;
import org.bouncycastle.crypto.engines.BlowfishEngine;
import org.bouncycastle.crypto.modes.CFBBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;

import javax.crypto.spec.SecretKeySpec;

public class BlowfishCipher extends Cipher {
    // encryption mode
    public static final int BLOWFISH_CFB = 16;
    private final int keyLength;
    private final StreamBlockCipher cipher;

    /**
     * <b>Notice: </b><br/>
     * 1. in <code>new CFBBlockCipher(engine, <b>8</b> * 8);</code> the IV length (8) is
     * reference to the shadowsocks's design.
     *
     * @see <a href="https://shadowsocks.org/en/spec/cipher.html">
     * https://shadowsocks.org/en/spec/cipher.html</a>#Cipher
     */
    public BlowfishCipher(String password, int mode) {
        key = new SecretKeySpec(password.getBytes(), "BF");
        keyLength = mode;
        BlowfishEngine engine = new BlowfishEngine();
        cipher = new CFBBlockCipher(engine, 8 * 8);
    }

    public static boolean isValidMode(int mode) {
        return mode == 16;
    }

    @Override
    protected void _init(boolean isEncrypt, byte[] iv) {
        String keyStr = new String(key.getEncoded());
        ParametersWithIV params = new ParametersWithIV(
                new KeyParameter(KeyHelper.generateKeyDigest(keyLength, keyStr)), iv);
        cipher.init(isEncrypt, params);
    }

    @Override
    protected byte[] _encrypt(byte[] originData) {
        byte[] encryptedData = new byte[originData.length];
        cipher.processBytes(originData, 0, originData.length, encryptedData, 0);
        return encryptedData;
    }

    @Override
    protected byte[] _decrypt(byte[] encryptedData) {
        byte[] originData = new byte[encryptedData.length];
        cipher.processBytes(encryptedData, 0, encryptedData.length, originData, 0);
        return originData;
    }

    @Override
    public int getIVLength() {
        return 8;
    }
}