⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blowfishengine.java

📁 这是linux下ssl vpn的实现程序
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
      0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
      0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
      0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
      0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
      0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
      0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
      0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
      0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
      0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
      0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
      0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
      0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
      0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
      0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
      0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
      0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
      0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
      0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
      0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
      0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
      0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
      0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
      0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
      0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
      0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
      0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
      0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
  };

  //====================================
  // Useful constants
  //====================================

  private static final int ROUNDS = 16;
  private static final int BLOCK_SIZE = 8; // bytes = 64 bits
  private static final int SBOX_SK = 256;
  private static final int P_SZ = ROUNDS + 2;

  private final int[] S0, S1, S2, S3; // the s-boxes
  private final int[] P; // the p-array

  private boolean encrypting = false;

  private byte[] workingKey = null;

  public BlowfishEngine() {
    S0 = new int[SBOX_SK];
    S1 = new int[SBOX_SK];
    S2 = new int[SBOX_SK];
    S3 = new int[SBOX_SK];
    P = new int[P_SZ];
  }

  /**
   * initialise a Blowfish cipher.
   *
   * @param forEncryption whether or not we are for encryption.
   * @param params the parameters required to set up the cipher.
   * @exception IllegalArgumentException if the params argument is
   * inappropriate.
   */
  public void init(
      boolean encrypting,
      byte[] key) {
    this.encrypting = encrypting;
    this.workingKey = key;
    setKey(this.workingKey);
    return;
  }

  public String getAlgorithmName() {
    return "Blowfish";
  }

  public final int processBlock(
      byte[] in,
      int inOff,
      byte[] out,
      int outOff) throws IOException {
    if (workingKey == null) {
      throw new IllegalStateException("Blowfish not initialised");
    }

    if ( (inOff + BLOCK_SIZE) > in.length) {
      throw new IOException("input buffer too short");
    }

    if ( (outOff + BLOCK_SIZE) > out.length) {
      throw new IOException("output buffer too short");
    }

    if (encrypting) {
      encryptBlock(in, inOff, out, outOff);
    }
    else {
      decryptBlock(in, inOff, out, outOff);
    }

    return BLOCK_SIZE;
  }

  public void reset() {
  }

  public int getBlockSize() {
    return BLOCK_SIZE;
  }

  //==================================
  // Private Implementation
  //==================================

  private int F(int x) {
    return ( ( (S0[ (x >>> 24)] + S1[ (x >>> 16) & 0xff])
              ^ S2[ (x >>> 8) & 0xff]) + S3[x & 0xff]);
  }

  /**
   * apply the encryption cycle to each value pair in the table.
   */
  private void processTable(
      int xl,
      int xr,
      int[] table) {
    int size = table.length;

    for (int s = 0; s < size; s += 2) {
      xl ^= P[0];

      for (int i = 1; i < ROUNDS; i += 2) {
        xr ^= F(xl) ^ P[i];
        xl ^= F(xr) ^ P[i + 1];
      }

      xr ^= P[ROUNDS + 1];

      table[s] = xr;
      table[s + 1] = xl;

      xr = xl; // end of cycle swap
      xl = table[s];
    }
  }

  private void setKey(byte[] key) {
    /*
     * - comments are from _Applied Crypto_, Schneier, p338
     * please be careful comparing the two, AC numbers the
     * arrays from 1, the enclosed code from 0.
     *
     * (1)
     * Initialise the S-boxes and the P-array, with a fixed string
     * This string contains the hexadecimal digits of pi (3.141...)
     */
    System.arraycopy(KS0, 0, S0, 0, SBOX_SK);
    System.arraycopy(KS1, 0, S1, 0, SBOX_SK);
    System.arraycopy(KS2, 0, S2, 0, SBOX_SK);
    System.arraycopy(KS3, 0, S3, 0, SBOX_SK);

    System.arraycopy(KP, 0, P, 0, P_SZ);

    /*
     * (2)
     * Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with the
     * second 32-bits of the key, and so on for all bits of the key
     * (up to P[17]).  Repeatedly cycle through the key bits until the
     * entire P-array has been XOR-ed with the key bits
     */
    int keyLength = key.length;
    int keyIndex = 0;

    for (int i = 0; i < P_SZ; i++) {
      // get the 32 bits of the key, in 4 * 8 bit chunks
      int data = 0x0000000;
      for (int j = 0; j < 4; j++) {
        // create a 32 bit block
        data = (data << 8) | (key[keyIndex++] & 0xff);

        // wrap when we get to the end of the key
        if (keyIndex >= keyLength) {
          keyIndex = 0;
        }
      }
      // XOR the newly created 32 bit chunk onto the P-array
      P[i] ^= data;
    }

    /*
     * (3)
     * Encrypt the all-zero string with the Blowfish algorithm, using
     * the subkeys described in (1) and (2)
     *
     * (4)
     * Replace P1 and P2 with the output of step (3)
     *
     * (5)
     * Encrypt the output of step(3) using the Blowfish algorithm,
     * with the modified subkeys.
     *
     * (6)
     * Replace P3 and P4 with the output of step (5)
     *
     * (7)
     * Continue the process, replacing all elements of the P-array
     * and then all four S-boxes in order, with the output of the
     * continuously changing Blowfish algorithm
     */

    processTable(0, 0, P);
    processTable(P[P_SZ - 2], P[P_SZ - 1], S0);
    processTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1);
    processTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2);
    processTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3);
  }

  /**
   * Encrypt the given input starting at the given offset and place
   * the result in the provided buffer starting at the given offset.
   * The input will be an exact multiple of our blocksize.
   */
  private void encryptBlock(
      byte[] src,
      int srcIndex,
      byte[] dst,
      int dstIndex) {
    int xl = BytesTo32bits(src, srcIndex);
    int xr = BytesTo32bits(src, srcIndex + 4);

    xl ^= P[0];

    for (int i = 1; i < ROUNDS; i += 2) {
      xr ^= F(xl) ^ P[i];
      xl ^= F(xr) ^ P[i + 1];
    }

    xr ^= P[ROUNDS + 1];

    Bits32ToBytes(xr, dst, dstIndex);
    Bits32ToBytes(xl, dst, dstIndex + 4);
  }

  /**
   * Decrypt the given input starting at the given offset and place
   * the result in the provided buffer starting at the given offset.
   * The input will be an exact multiple of our blocksize.
   */
  private void decryptBlock(
      byte[] src,
      int srcIndex,
      byte[] dst,
      int dstIndex) {
    int xl = BytesTo32bits(src, srcIndex);
    int xr = BytesTo32bits(src, srcIndex + 4);

    xl ^= P[ROUNDS + 1];

    for (int i = ROUNDS; i > 0; i -= 2) {
      xr ^= F(xl) ^ P[i];
      xl ^= F(xr) ^ P[i - 1];
    }

    xr ^= P[0];

    Bits32ToBytes(xr, dst, dstIndex);
    Bits32ToBytes(xl, dst, dstIndex + 4);
  }

  private int BytesTo32bits(byte[] b, int i) {
    return ( (b[i] & 0xff) << 24) |
        ( (b[i + 1] & 0xff) << 16) |
        ( (b[i + 2] & 0xff) << 8) |
        ( (b[i + 3] & 0xff));
  }

  private void Bits32ToBytes(int in, byte[] b, int offset) {
    b[offset + 3] = (byte) in;
    b[offset + 2] = (byte) (in >> 8);
    b[offset + 1] = (byte) (in >> 16);
    b[offset] = (byte) (in >> 24);
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -