Дневник Шестеро Михаила

Oct. 6th, 2014

03:42 pm - Сжатие потока информации PHP-HTTP-Java

Это логическое продолжение моих статей «Сжатие потока информации PHP-HTTP-Qt» и «Шифровка потока информации PHP-HTTP-Java».

Перед вами код на Java, способный конвеерно принимать запакованный (как в первой упомянутой статье) и возможно зашифрованный (как во второй) XML:


import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
// ................


public static void main(String[] args
{
  System.out.println("DecryptorTest HELLO");
  
  //Security.addProvider( new IAIK() ); // using IAIK Security Provider
  java.security.Security.addProvider(new gnu.crypto.jce.GnuCrypto());
  
  // Using Hex in Apache Commons:
  // byte[] bytes = Hex.decodeHex(key0.toCharArray());
  StringBuilder keyc = new StringBuilder();
    for (int i = 0; i < key0.length(); i+=2) {
        String str = key0.substring(i, i+2);
        keyc.append((char)Byte.parseByte(str, 16));
    }
  System.out.println("DecryptorTest: Common secret key (plain) =" + keyc);

  MD5 md5 = new MD5();
  //IMessageDigest md5 = HashFactory.getInstance("MD5");
  byte[] iv;
  try {
    iv = iv0.getBytes"UTF-8" );
  catch (UnsupportedEncodingException e1) {
    System.out.println("DecryptorTest: Error: UnsupportedEncodingException (UTF-8)");
    return;
  }
  System.out.println("DecryptorTest: Common initialization vector length (bytes) =" + iv.length);
  md5.update(iv, 0, iv.length);
  String ivh = "";
  iv = md5.digest();
  for (int i = 0; i < iv.length; i++) {
    ivh += String.format("%02x", iv[i] );
  }
  System.out.println("DecryptorTest: Common initialization vector (MD5) =" + ivh);

  // encrypt the user password and convert it to Hex
  String passwordh;
  try {
    passwordh = encryptpassword0, keyc.toString(), iv );
  catch InvalidKeyException 
      | UnsupportedEncodingException 
      | IllegalBlockSizeException 
      | BadPaddingException 
      | NoSuchAlgorithmException 
      | NoSuchProviderException 
      | NoSuchPaddingException 
      | InvalidAlgorithmParameterException e
  {
    System.out.println("DecryptorTest: Error: cannot encrypt user password! Exception="+e.toString());
    return;
  }
  System.out.println("DecryptorTest: Personal password (encripted, hex) =" + passwordh);
  
  md5.reset();
  try {
    md5.update(password0.getBytes("UTF-8")0, password0.getBytes("UTF-8").length);
  catch (UnsupportedEncodingException e) {
    System.out.println("DecryptorTest: Error: cannot prepare password (no UTF-8 encoding)");
    return;
  }
  byte[] pwd5 = md5.digest();
  //System.out.println("DecryptorTest: Personal password (MD5, hex) =" + password5);
  
  int keysize;
  keysize = 32// Cipher.getMaxAllowedKeyLength("Twofish/CBC/NoPadding");
  System.out.println("DecryptorTest: maximum key size ="+keysize );
  
  URL url;
  try {
    url = new URL(surl);
  catch (MalformedURLException e) {
    System.out.println("DecryptorTest: Error: Malformed URL");
    return;
  }
    HttpURLConnection conn;
  try {
    conn = (HttpURLConnectionurl.openConnection();
    String post;
    
    post = "user=shestero";
    post+= "&password="+passwordh;
    
    conn.setDoOutput(true)// мы будем писать POST данные
    conn.setDoInput(true);

    OutputStreamWriter out =
        new OutputStreamWriterconn.getOutputStream()"UTF-8" );
    out.write(post);
    // out.write("\r\n"); // перевод строки попадает в значения, передаваемые POST-ом
    out.close();
    
    PushbackInputStream stream = new PushbackInputStreamconn.getInputStream());
    int i0 = stream.read();
    if (i0<0)
    {
      System.out.println("DecryptorTest: Warning: empty reply!");
    }
    else
    {
      stream.unread(i0);
      
      InflaterInputStream inf = null;
      if (i0==0)
      {
        // encrypted
        stream.skip(32)// skip header
        
        System.out.println("DecryptorTest: Note: data comes encrypted!");
        
        byte[] key2 = new byte[32];
        Arrays.fill(key2,(byte)0);
        int j=0;
        for (int i=0; i<keyc.length() || i<pwd5.length; i++)
        {
          if (i<keyc.length()) key2[j++]=keyc.toString().substring(i,i+1).getBytes()[0];
          if (i<pwd5.lengthkey2[j++]=pwd5[i];
          if (j>=keysize)
            break;
        }
        System.out.println("DecryptorTest: Personal key to decript reply =["+key2+"]");

        // TODO: Fix key size
        if (j<=16j=16else if (j<=24j=24else if (j<32j=32;
        System.out.println("DecryptorTest: key2.length="+j);
        Cipher cipher = createCipherCipher.DECRYPT_MODE, key2, iv );
        
        inf = new InflaterInputStream
            new CipherInputStreamstream, cipher )
            new Inflater(true// set 'nowrap' parameter to 'true' here 
            );
        // r = new BufferedReader( new InputStreamReader( new CipherInputStream( stream, cipher ) ) );
      }
      else
      {
        // plain
        System.out.println("DecryptorTest: Warning: data comes unencrypted!");

        inf = new InflaterInputStreamstream, new Inflater(true) );
        //r = new BufferedReader( new InputStreamReader( stream ) );
      }
      BufferedReader r = new BufferedReadernew InputStreamReaderinf ) );    
      
      // Чтение строка за строкой для проверки
      System.out.println("====[REPLY FROM SERVER:]===========================");
          String inputLine;
          while ((inputLine = r.readLine()) != null
          {
              System.out.println(inputLine);
          }
          r.close();
          System.out.println("====[SUCESS]=======================================");
    }          
    catch (IOException e) {
    System.out.println("DecryptorTest: Error: IOException; URL="+surl);
  catch InvalidKeyException
      |  NoSuchAlgorithmException
      |  NoSuchProviderException
      |  NoSuchPaddingException
      |  InvalidAlgorithmParameterException e
  {
    System.out.println("DecryptorTest: Error: cannot decode: Exception="+e.toString());
  
  
  System.out.println("DecryptorTest BYE")
}
Исходник обработан: Java2html

Tags: , , ,
Current Mood: busy

Apr. 22nd, 2014

08:06 pm - Шифровка потока информации PHP-HTTP-Java (GNU-JCE, IAIK-JCE)

Это дополнение к моей предыдущей статье «Шифровка потока информации PHP-HTTP-Qt». Для того что бы понять о чём тут речь, прочитайте её сначала. Здесь приводится простенькая демонстрационная программа-клиент на Java, которая делает то же самое, что я сделал там на C++/Qt, то есть обеспечивает приём и расшифровку данных по тому же протоколу. Она работает с тем же самым серверным скриптом на PHP. Принятые расшифрованные данные (в моём случае XML) выводятся в стандартный поток вывода. Вот исходный код (URL-скрипта и пароли я естесвенно убрал):

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.lang.reflect.Array;

import java.io.*;
import java.net.*;
import java.security.*;

import javax.crypto.*;
import javax.crypto.spec.*;

import gnu.crypto.Registry;

import gnu.crypto.hash.MD5;

import gnu.crypto.jce.GnuCrypto;          // GNU-JCE  провайдер алгоритма TwoFish
// import iaik.security.provider.IAIK;    // IAIK-JCE провайдер алгоритма TwoFish


public class MainClass {

  final static String surl = "http://......./xml.php"// "baseurl()+"/xml.php";
  final static String iv0  = "i.vector";
  final static String key0 = ".............."// Hex encoded
  final static String password0 = "........."// personal password in plain text
  
  
  
  // prepare cipher
  public static Cipher createCipher(int mode, byte[] key, byte[] ivBytesthrows 
      UnsupportedEncodingException, 
      NoSuchAlgorithmException, 
      NoSuchProviderException, 
      NoSuchPaddingException, 
      InvalidKeyException, 
      InvalidAlgorithmParameterException
  {
     IvParameterSpec iv = new IvParameterSpec(ivBytes);
     SecretKey secretKey = new SecretKeySpeckey, "Twofish" )
     
     // get Cipher and init it for encryption
     
     //Cipher cipher = Cipher.getInstance("Twofish/CBC/NoPadding", "IAIK");       // IAIK
     Cipher cipher = Cipher.getInstance("Twofish/CBC/NoPadding", Registry.GNU_CRYPTO);     // GNU
     
     cipher.initmode, secretKey, iv );

     return cipher;
  }

  // encrypt string
  public static String encrypt(String source, String key, byte[] iv
      throws 
      UnsupportedEncodingException, 
      InvalidKeyException, 
      IllegalBlockSizeException, 
      BadPaddingException, 
      NoSuchAlgorithmException, 
      NoSuchProviderException, 
      NoSuchPaddingException, 
      InvalidAlgorithmParameterException 
  {
     Cipher cipher = createCipherCipher.ENCRYPT_MODE, key.getBytes("UTF-8"), iv )
     
     // encrypt data
     while source.length() % cipher.getBlockSize() !=source+="\0"// padding
     byte[] cipherText = cipher.doFinalsource.getBytes("UTF-8") );

     // перевод cipherText в HEX-представление
     String encryptedString = "";
     for (int i = 0; i < cipherText.length; i++) {
      encryptedString += String.format("%02x", cipherText[i]);
     // encryptedText = Base64Coder.encodeLines(encryptedText);
     
     return encryptedString;
  }
  
  public static void main(String[] args) {
    
    System.out.println("DecryptorTest HELLO");
    
    // Security.addProvider( new IAIK() ); // using IAIK Security Provider
    java.security.Security.addProvider(new GnuCrypto());
    
    // Using Hex in Apache Commons:
    // byte[] bytes = Hex.decodeHex(key0.toCharArray());
    StringBuilder keyc = new StringBuilder();
    for (int i = 0; i < key0.length(); i+=2) {
      String str = key0.substring(i, i+2);
      keyc.append((char)Byte.parseByte(str, 16));
    }
    System.out.println("DecryptorTest: Common secret key (plain) =" + keyc);

    MD5 md5 = new MD5();
    //IMessageDigest md5 = HashFactory.getInstance("MD5");
    byte[] iv;
    try {
      iv = iv0.getBytes"UTF-8" );
    catch (UnsupportedEncodingException e1) {
      System.out.println("DecryptorTest: Error: UnsupportedEncodingException (UTF-8)");
      return;
    }
    System.out.println("DecryptorTest: Common initialization vector length (bytes) =" + iv.length);
    md5.update(iv, 0, iv.length);
    String ivh = "";
    iv = md5.digest();
    for (int i = 0; i < iv.length; i++) {
      ivh += String.format("%02x", iv[i] );
    }
    System.out.println("DecryptorTest: Common initialization vector (MD5) =" + ivh);

    // encrypt the user password and convert it to Hex
    String passwordh;
    try {
      passwordh = encryptpassword0, keyc.toString(), iv );
    catch InvalidKeyException 
        | UnsupportedEncodingException 
        | IllegalBlockSizeException 
        | BadPaddingException 
        | NoSuchAlgorithmException 
        | NoSuchProviderException 
        | NoSuchPaddingException 
        | InvalidAlgorithmParameterException e
    {
      System.out.println("DecryptorTest: Error: cannot encrypt user password! Exception="+e.toString());
      return;
    }
    System.out.println("DecryptorTest: Personal password (encripted, hex) =" + passwordh);
    
    md5.reset();
    try {
      md5.update(password0.getBytes("UTF-8")0, password0.getBytes("UTF-8").length);
    catch (UnsupportedEncodingException e) {
      System.out.println("DecryptorTest: Error: cannot prepare password (no UTF-8 encoding)");
      return;
    }
    byte[] pwd5 = md5.digest();
    //System.out.println("DecryptorTest: Personal password (MD5, hex) =" + password5);
    
    int keysize;
    keysize = 32// Cipher.getMaxAllowedKeyLength("Twofish/CBC/NoPadding");
    System.out.println("DecryptorTest: maximum key size ="+keysize );
    
    URL url;
    try {
      url = new URL(surl);
    catch (MalformedURLException e) {
      System.out.println("DecryptorTest: Error: Malformed URL");
      return;
    }
    
    HttpURLConnection conn;
    InputStream stream;
    try {
      conn = (HttpURLConnectionurl.openConnection();
      String post;
      
      post = "user=shestero";
      post+= "&password="+passwordh;
      
      conn.setDoOutput(true)// мы будем писать POST данные
      conn.setDoInput(true);

      OutputStreamWriter out =
          new OutputStreamWriterconn.getOutputStream()"UTF-8" );
      out.write(post);
      // out.write("\r\n"); // перевод строки попадает в значения, передаваемые POST-ом
      out.close();
      
      stream = conn.getInputStream();
      stream.mark(1);
      int i0 = 0;//stream.read();
      BufferedReader r;      
      if (i0==0)
      {
        stream.skip(32)// skip header
        
        // encrypted
        System.out.println("DecryptorTest: Note: data comes encrypted!");
        
        byte[] key2 = new byte[32];
        Arrays.fill(key2,(byte)0);
        int j=0;
        for (int i=0; i<keyc.length() || i<pwd5.length; i++)
        {
          if (i<keyc.length()) key2[j++]=keyc.toString().substring(i,i+1).getBytes()[0];
          if (i<pwd5.lengthkey2[j++]=pwd5[i];
          if (j>=keysize)
            break;
        }
        System.out.println("DecryptorTest: Personal key to decript reply =["+key2+"]");

        // TODO: Fix key size
        if (j<=16j=16else if (j<=24j=24else if (j<32j=32;
        System.out.println("DecryptorTest: key2.length="+j);
        Cipher cipher = createCipherCipher.DECRYPT_MODE, key2, iv );
        
        r = new BufferedReadernew InputStreamReadernew CipherInputStreamstream, cipher ) ) );
      }
      else
      {
        // plain
        stream.reset();
        r = new BufferedReadernew InputStreamReaderstream ) );
        System.out.println("DecryptorTest: Warning: data comes unencrypted!");
      }
      
      // Чтение строка за строкой для проверки
      System.out.println("====[REPLY FROM SERVER:]===========================");
          String inputLine;
          while ((inputLine = r.readLine()) != null
          {
              System.out.println(inputLine);
          }
          r.close();
          System.out.println("====[SUCESS]=======================================");
          
      catch (IOException e) {
      System.out.println("DecryptorTest: Error: IOException; URL="+surl);
    catch InvalidKeyException
        |  NoSuchAlgorithmException
        |  NoSuchProviderException
        |  NoSuchPaddingException
        |  InvalidAlgorithmParameterException e
    {
      System.out.println("DecryptorTest: Error: cannot decode: Exception="+e.toString());
    
    
    System.out.println("DecryptorTest BYE")
  }

}
Исходник обработан: Java2html

Ради алгоритма Twofish я использовал из GNU-JCE , а также пробовал коммерческий IAIK с закрытым исходным кодом.

См. также: http://www.cryptix.org , http://bouncycastle.org

Tags: , , , , , , ,