Package anvil.core.crypto

Source Code of anvil.core.crypto.AnyCipher

/*
* $Id: AnyCipher.java,v 1.19 2002/09/16 08:05:02 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.core.crypto;

import anvil.core.Any;
import anvil.core.AnyBinary;
import anvil.core.AnyAbstractClass;
import anvil.script.Context;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

///
/// @class Cipher
/// Used for encrypting and decrypting data.
/// Using symmetric algorithms: <i>DES, TripleDES, Blowfish</i>.
///

/**
* class AnyCipher
*
* @author: Jaripekka Salminen
*/
public class AnyCipher extends AnyAbstractClass
{
  public static final anvil.script.compiler.NativeClass __class__ =
    new anvil.script.compiler.NativeClass("Cipher", AnyCipher.class,
    //DOC{{
    ""+
      "\n" +
      " @class Cipher\n" +
      " Used for encrypting and decrypting data.\n" +
      " Using symmetric algorithms: <i>DES, TripleDES, Blowfish</i>.\n" +
      "\n" +
      " @method update\n" +
      "   Continues a multiple-part encryption or decryption\n" +
      "   operation (depending on how this cipher was initialized),\n" +
      "   processing another data part. \n" +
      " @synopsis binary update(object data [, int offset, int length] )\n" +
      " @param data string or binary data\n" +
      " @param offset offset in data\n" +
      " @param length length of data\n" +
      " @return processed data\n" +
      " @method final\n" +
      " @synopsis binary final() ;\n" +
      "   Finishes a multiple-part encryption or decryption\n" +
      "   operation, depending on how this cipher was initialized.\n" +
      " @synopsis binary final(object data [, int offset, int length] ) ;\n" +
      "   Encrypts or decrypts data in a single-part operation, or\n" +
      "   finishes a multiple-part operation.\n" +
      " @param data string or binary data\n" +
      " @param offset offset in data\n" +
      " @param length length of data\n" +
      " @return processed data\n"
    //}}DOC
    );
  static {
    CryptoModule.class.getName();
  }
 
  private Cipher _cipher;

  /**
   * @param algorithm = DES | DESede | Blowfish
   * @param opmode = Cipher.ENCRYPT_MODE | Ciper.DECRYPT_MODE
   */
  public AnyCipher(String algorithm, int opmode, Any anyKey)
    throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
    InvalidAlgorithmParameterException, IOException
  {
    String mode = "CBC"; // ECB | CBC | CFB | OFB | PCPC
    String padding = "PKCS5Padding"; // NoPadding | PKCS5Padding | SSL3Padding
    StringBuffer transformation = new StringBuffer(algorithm);
    transformation.append('/');
    transformation.append(mode);
    transformation.append('/');
    transformation.append(padding);
    _cipher = Cipher.getInstance(transformation.toString());

    byte [] key;
    int key_length;
    if (anyKey.isBinary()) {
      key = (byte[])anyKey.toBinary();
      key_length = anyKey.sizeOf();
    } else {
      key = anvil.util.Conversions.getBytes(anyKey.toString());
      key_length = key.length;
    }

    if (algorithm.equals("DES")) {
      byte[] deskey = new byte[8];
      for (int i=0; i<8; i++) {
        if (i < key_length) {
          deskey[i] = key[i];
        } else {
          deskey[i] = 0;
        }
      }
      key = (new DESKeySpec(deskey)).getKey();

    } else if (algorithm.equals("DESede")) {
      byte[] desedekey = new byte[24];
      for (int i=0; i<24; i++) {
        if (i < key_length) {
          desedekey[i] = key[i];
        } else {
          desedekey[i] = 0;
        }
      }
      key = (new DESedeKeySpec(desedekey)).getKey();
    }

    SecretKey secretKey = new SecretKeySpec(key,algorithm);

    /* DES in ECB mode does not require any parameters */
    if (mode.equals("ECB")) {
      _cipher.init(opmode, secretKey);

    /* DES in CBC mode requires an initialization vector (IV) parameter */
    } else if (mode.equals("CBC")) {
      byte[] iv = new byte[8];
      IvParameterSpec ivSpec = new IvParameterSpec(iv);
      _cipher.init(opmode, secretKey, ivSpec);

    } else {
      _cipher.init(opmode, secretKey);
    }
  }


  /**
   *
   */ 
 
  public final anvil.script.ClassType classOf() {
    return __class__;
  }
 
  /**
   *
   */ 
  public Object toObject()
  {
    return _cipher;
  }

  /**
   *
   */
 

  /// @method update
  ///   Continues a multiple-part encryption or decryption
  ///   operation (depending on how this cipher was initialized),
  ///   processing another data part.
  /// @synopsis binary update(object data [, int offset, int length] )
  /// @param data string or binary data
  /// @param offset offset in data
  /// @param length length of data
  /// @return processed data
  public Any m_update(Context context, Any[] parameters)
  {
    if (parameters.length > 0) {
      try {
        Any param = parameters[0];
        byte[] data;
        int size;
        if (param.isBinary()) {
          data = param.toBinary();
          size = param.sizeOf();
        } else {
          data = anvil.util.Conversions.getBytes(param.toString());
          size = data.length;
        }
        if (parameters.length > 2) {
          int offset = parameters[1].toInt();
          int length = parameters[2].toInt();
          if (offset < 0) {
            offset = 0;
          }
          if (offset >= size) {
            new AnyBinary();
          }
          if (offset + length > size) {
            length = size - offset;
          }
          return Any.create(_cipher.update(data, offset, length));

        } else {
          return Any.create(_cipher.update(data, 0, size));
        }
      } catch (Exception e) {
        throw context.exception(e);
      }
    } else {
      throw parametersMissing(context, "final");
    }
  }


  /// @method final
  /// @synopsis binary final() ;
  ///   Finishes a multiple-part encryption or decryption
  ///   operation, depending on how this cipher was initialized.
  /// @synopsis binary final(object data [, int offset, int length] ) ;
  ///   Encrypts or decrypts data in a single-part operation, or
  ///   finishes a multiple-part operation.
  /// @param data string or binary data
  /// @param offset offset in data
  /// @param length length of data
  /// @return processed data
  public Any m_final(Context context, Any[] parameters)
  {
    try {
      if (parameters.length > 0) {
        Any param = parameters[0];
        byte[] data;
        int size;
        if (param.isBinary()) {
          data = param.toBinary();
          size = param.sizeOf();
        } else {
          data = anvil.util.Conversions.getBytes(param.toString());
          size = data.length;
        }
        if (parameters.length > 2) {
          int offset = parameters[1].toInt();
          int length = parameters[2].toInt();
          if (offset < 0) {
            offset = 0;
          }
          if (offset >= size) {
            return Any.create(_cipher.doFinal());
          }
          if (offset + length > size) {
            length = size - offset;
          }
          return Any.create(_cipher.doFinal(data, offset, length));

        } else {
          return Any.create(_cipher.doFinal(data, 0, size));
        }
      } else {
        return Any.create(_cipher.doFinal());
      }
    } catch (Exception e) {
      throw context.exception(e);
    }
  }


}
TOP

Related Classes of anvil.core.crypto.AnyCipher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.