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

📄 richrsacipher.java

📁 加密算法
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    /*
     * 1. If x = 256l, output  "integer too large " and stop.
     */
    int j = (x.bitLength() + 7) / 8;

    if (l == -1)
     {
      l = j;
    }

    if ((j > l) || (x.signum() == -1))
     {
      throw new IllegalBlockSizeException("Block too large");
    }

    /*
     * 2. Write the integer x in its unique l-digit representation
     * base 256: x = xl- 1 256^ (l- 1) + xl -2 256 256^(l -2) + ...& + x1 256 + x0
     * where 0 = xi < 256 (note that one or more leading digits
     * will be zero if x < 256^ (l- 1)).
     */
    byte[] C = x.toByteArray();

    /*
     * remove the leading zeros
     */
    int index = 0;

    for (; (index < C.length) && (C[index] == 0); index++);

    if (index > 0)
     {
      byte[] temp = new byte[C.length - index];

      System.arraycopy(C, index, temp, 0, temp.length);

      C = temp;
    }
    else if (C.length > l)
     {
      throw new IllegalBlockSizeException("Block too large");
    }

    /*
     * 3. Let the octet Xi have the value xl -i for 1 = i = l.
     * Output the octet string X = X1 X2 & ... Xl.
     */
    if (C.length == l)
     {
      return C;
    }

    /*
     * C is not long enough
     */
    byte[] result = new byte[l];

    System.arraycopy(C, 0, result, l - C.length, C.length);

    return result;
  }

  /**
   * Method encrypt
   * Description: Encrypt with pad
   * See PKCS#1
   * @param M the plaintext message
   */
  private byte[] encrypt(byte[] M)
          throws IllegalBlockSizeException
   {

    /*
     * RSA Steps according to PKCS #1 v 2.0 pg 15 for encryption:
     * 1. Apply the EME-PKCS1-v1_5 encoding operation (Section 9.1.2.1)
     * to the message M to produce an encoded message EM of length k-1
     * octets: EM = EME-PKCS1-V1_5-ENCODE (M, k-1)
     * If the encoding operation outputs  "message too long,  ," then output
     * message too long  and stop.
     */
    int    k  = params_.getKeysize();
    byte[] EM = EME_PKCS1_V1_5_ENCODE(M, k-1);

    /*
     * 2. Convert the encoded message EM to an integer message
     * representative m:  m = OS2IP (EM)
     */
    BigInteger m = new BigInteger(1, EM);

    /*
     * 3. Apply the RSAEP encryption primitive (Section 5.1.1) to the
     * public key (n, e) and the message representative m to produce
     * an integer ciphertext representative c: c = RSAEP ((n, e), m)
     */
    BigInteger c = RSAEP((RSAPublicKey) key_, m);

    /*
     * 4. Convert the ciphertext representative c to a ciphertext C of
     * length k octets: C = I2OSP (c, k)
     */
    byte[] C = I2OSP(c, k);

    /*
     * 5. Output the ciphertext C.
     */
    return C;
  }

  /**
   * Method decrypt
   * Description: Decrypt with pad
   * See PKCS#1
   * @param M the ciphertext message
   */
  private byte[] decrypt(byte[] C)
          throws BadPaddingException, IllegalBlockSizeException
   {

    /*
     * RSA Steps according to PKCS #1 v 2.0 pg 16 for decryption:
     * 1. If the length of the ciphertext C is not k octets, output
     * decryption error  and stop.
     */
    int k = params_.getKeysize();

    if (k != C.length)
     {
      throw new IllegalBlockSizeException("decryption error");
    }

    /*
     * 2. Convert the ciphertext C to an integer ciphertext
     * representative c: c = OS2IP (C)
     */
    BigInteger c = new BigInteger(1, C);

    /*
     * 3. Apply the RSADP decryption primitive to the private
     * key (n, d) and the ciphertext representative c to produce
     * an integer message representative m: m = RSADP ((n, d), c)
     * If RSADP outputs  ciphertext out of range,  then output
     * decryption error  and stop.
     */
    BigInteger m = RSADP((RSAPrivateKey) key_, c);

    /*
     * 4. Convert the message representative m to an encoded message
     * EM of length k-1 octets: EM = I2OSP (m, k-1)
     * If I2OSP outputs  integer too large,  then output  decryption
     * error  and stop.
     */
    byte[] EM = I2OSP(m, k - 1);

    /*
     * 5. Apply the EME-PKCS1-v1_5 decoding operation to the encoded
     * message EM to recover a message M: M = EME-PKCS1-V1_5-DECODE(EM)
     * If the decoding operation outputs  decoding error,  then output
     * decryption error and stop.
     */
    byte[] M = EME_PKCS1_V1_5_DECODE(EM);

    /*
     * 6. Output the message M.
     */
    return M;
  }

  /**
   * Method EME_PKCS1_V1_5_ENCODE
   * Description: Pad encoding
   *
   * @param M the ciphertext message
   * @param emLen the length of encr message
   *
   * @return encoded pad
   *
   * @throws IllegalBlockSizeException
   *
   */
  private byte[] EME_PKCS1_V1_5_ENCODE(byte[] M, int emLen)
          throws IllegalBlockSizeException
   {

    /*
     * Section 9.1.2.1 of PKCS#1v2.0
     * 1. If the length of the message M is greater than emLen   10
     * octets, output  message too long  and stop.
     */
    if (M.length > emLen - 10)
     {
      throw new IllegalBlockSizeException("message too long");
    }

    /*
     * 2. Generate an octet string PS of length emLen-||M||-2
     * consisting of pseudorandomly generated nonzero octets.
     * The length of PS will be at least 8 octets.
     */
    byte[]                PS   =
      new byte[(emLen - M.length - 2)];

    // Fill the padding string with random non-zero bytes
    for (int i = 0; i < PS.length; i++)
     {
      PS[i] = (byte) (random_.nextInt(255) + 1);
    }

    /*
     * 3. Concatenate PS, the message M, and other padding to
     * form the encoded message EM as EM = 02 || PS || 00 || M
     */
    byte[] EM = new byte[emLen];
    int index = 0;
    EM[index++] = (byte) 0x02;
    for (int i = 0; i < PS.length; i++)
     {
      EM[index++] = PS[i];
    }
    EM[index++] = (byte) 0x00;
    for (int i = 0; i < M.length; i++)
     {
      EM[index++] = M[i];
    }

    /*
     * 4. Output EM.
     */
    return EM;
  }

  /**
   * Method EME_PKCS1_V1_5_DECODE
   * Description: Pad decoding
   *
   * @param EM the encrypted message
   *
   * @return pad
   *
   * @throws BadPaddingException
   *
   */
  private byte[] EME_PKCS1_V1_5_DECODE(byte[] EM)
          throws BadPaddingException
   {

    /*
     * Section 9.1.2.2 of PKCS#1v2.0
     * 1. If the length of the encoded
     * message EM is less than 10, output  decoding error
     * and stop.
     */
    if (EM.length < 10)
     {
      throw new BadPaddingException("message too short");
    }

    /*
     * 2. Separate the encoded message EM into an octet string PS
     * consisting of nonzero octets and a message M as
     * EM = 02 || PS || 00 || M. If the first octet of EM is not 02,
     * or if there is no 00 octet to separate PS from M,
     * output  decoding error  and stop.
     */
    if (EM[0] != (byte) 0x02)
     {
      throw new BadPaddingException(
        "message not formatted properly");
    }

    // Need to start by looking for the first non-zero byte
    int start = 0;

    while (EM[start] != (byte) 0x00)
     {
      start++;

      if (start >= EM.length)
       {
        throw new BadPaddingException("bad padding");
      }
    }

    start++;  // Ignore the first 00

    /*
     * 3. If the length of PS is less than 8 octets,
     * output  decoding error  and stop.
     */
    if (start < 10)
     {
      throw new BadPaddingException("bad padding");
    }

    byte[] M = new byte[EM.length - start];

    System.arraycopy(EM, start, M, 0, M.length);

    /*
     * 4. Output M.
     */
    return M;
  }

  /**
   * Method RSEAP
   * Description: Performs the encryyrption
   *
   * @param publicKey the RSA public key
   * @param m the plaintext integer
   *
   * @return the ciphertext integer
   *
   * @throws IllegalBlockSizeException
   *
   */
  private BigInteger RSAEP(RSAPublicKey publicKey, BigInteger m)
          throws IllegalBlockSizeException
   {

    /*
     * RSAEP ((n, e), m)
     * Input: (n, e) RSA public key
     * m message representative, an integer between 0 and n-1
     * Output: c ciphertext representative, an integer between 0 and
     * n-1; or message representative out of range
     * Assumptions: public key (n, e) is valid
     */
    BigInteger e = publicKey.getPublicExponent();
    BigInteger n = publicKey.getModulus();

    /*
     * 1. If the message representative m is not between 0 and n-1,
     * output  message representative out of range  and stop.
     */
    BigInteger nMinusOne = n.subtract(BigInteger.ONE);

    /*
     * m > 0 and m < n-1
     */
    if (m.compareTo(BigInteger.ZERO) < 0)
     {
      throw new IllegalBlockSizeException(
        "Ciphertext too small");
    }

    if (m.compareTo(nMinusOne) > 0)
     {
      throw new IllegalBlockSizeException(
        "Ciphertext too large");
    }

    /*
     * 2. Let c = me mod n.
     */
    BigInteger c = m.modPow(e, n);

    /*
     * 3. Output c.
     */
    return c;
  }

  /**
   * Method RSADP
   * Description: Performs the decryyrption
   *
   * @param K the RSA Private Key
   * @param c an integer representing
   * the cipher
   *
   * @return the plaintext integer
   *
   */
  private BigInteger RSADP(RSAPrivateKey K,
                          BigInteger c)
   {


    /*
     * RSADP (K, c)
     * Input: K RSA private key, where K has one of the following
     * forms: a pair (n, d)
     *   a quintuple (p, q, dP, dQ, qInv)
     * c ciphertext representative, an integer between 0 and n-1
     * Output: m message representative, an integer between 0 and n-1; or
     *  ciphertext representative out of range
     * Assumptions: private key K is valid
     * Steps:
     * 1. If the ciphertext representative c is not between 0 and n-1,
     * output  ciphertext representative out of range  and stop.
      */

    /*
     * 2.1 Let m = cd mod n.
     * PKCS #1 V2.0: RSA CRYPTOGRAPHY STANDARD 9
     * Else, if the second form (p, q, dP, dQ, qInv) of K is used:
     */
    if (!(K instanceof RSAPrivateCrtKey))//RSAPrivateCrtKey是继承RSAPrivateKey的一个类.
      /* jdk1.5的API中是如此说明的:
         The interface to an RSA private key, as defined in the PKCS#1 standard, using the Chinese Remainder Theorem (CRT) information values.
      */

     {

      BigInteger d = K.getPrivateExponent();
      BigInteger n = K.getModulus();

      BigInteger m = c.modPow(d, n);

      return m;
    }

    /*
     * 2. If the first form (n, d) of K is used:
     */
    RSAPrivateCrtKey privateCrtKey =
      (RSAPrivateCrtKey) K;
    BigInteger       p             = privateCrtKey.getPrimeP();
    BigInteger       q             = privateCrtKey.getPrimeQ();
    BigInteger       dP            =
      privateCrtKey.getPrimeExponentP();
    BigInteger       dQ            =
      privateCrtKey.getPrimeExponentQ();
    BigInteger       qInv          =
      privateCrtKey.getCrtCoefficient();

    /*
     * 2.2 Let m1 = cdP mod p.
     */
    BigInteger m1 = c.modPow(dP, p);

    /*
     * 2.3 Let m2 = cdQ mod q.
     */
    BigInteger m2 = c.modPow(dQ, q);

    /*
     * 2.4 Let h = qInv ( m1   m2 ) mod p.
     */
    BigInteger h = m1.subtract(m2);

    h = h.multiply(qInv);
    h = h.mod(p);

    /*
     * 2.5 Let m = m2 + h q.
     */
    BigInteger m = h.multiply(q);

    m = m.add(m2);

    /*
     * 3. Output m.
     */
    return m;
  }
}

⌨️ 快捷键说明

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