Android Open Source - steamchat Cryptography






From Project

Back to project page steamchat.

License

The source code is released under:

Apache License

If you think the Android project steamchat listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.kevelbreh.steamchat.steam.security;
// w w  w. ja  va 2 s.com
import com.kevelbreh.steamchat.steam.util.JenkinsHash;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.nio.ByteBuffer;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;
import java.util.zip.CRC32;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * Provides cryptography functions used in Steam protocols
 */
final public class Cryptography {

    /**
     * Private constructor.  We don't want people making an instant of this class.
     */
    private Cryptography() {
        throw new AssertionError();
    }

    /**
     * Performs an SHA1 hash of an input byte array
     */
    public static byte[] SHAHash(byte[] input) {
        try {
            final MessageDigest md = MessageDigest.getInstance("SHA-1");
            return md.digest(input);
        } catch (final NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Performs an encryption using AES/CBC/PKCS7 with an input byte array and key, with a random IV prepended using AES/ECB/None
     */
    public static byte[] SymmetricEncrypt(byte[] input, byte[] key) {
        try {
            Security.addProvider(new BouncyCastleProvider());

            // encrypt iv using ECB and provided key
            Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding", "BC");
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"));

            // generate iv
            final byte[] iv = GenerateRandomBlock(16);
            final byte[] cryptedIv = cipher.doFinal(iv);

            // encrypt input plaintext with CBC using the generated (plaintext) IV and the provided key
            cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));

            final byte[] cipherText = cipher.doFinal(input);

            // final output is 16 byte ecb crypted IV + cbc crypted plaintext
            final byte[] output = new byte[cryptedIv.length + cipherText.length];
            System.arraycopy(cryptedIv, 0, output, 0, cryptedIv.length);
            System.arraycopy(cipherText, 0, output, cryptedIv.length, cipherText.length);

            return output;
        } catch (final InvalidKeyException e) {
            e.printStackTrace();
        } catch (final InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (final NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (final NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (final IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (final BadPaddingException e) {
            e.printStackTrace();
        } catch (final NoSuchProviderException e) {
            e.printStackTrace();
        }
        return new byte[0];
    }

    /**
     * Decrypts using AES/CBC/PKCS7 with an input byte array and key, using the random IV prepended using AES/ECB/None
     */
    public static byte[] SymmetricDecrypt(byte[] input, byte[] key) {
        try {
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding", "BC");

            // first 16 bytes of input is the ECB encrypted IV
            byte[] iv = new byte[16];
            final byte[] cryptedIv = Arrays.copyOfRange(input, 0, 16);

            // the rest is ciphertext
            byte[] cipherText = new byte[input.length - cryptedIv.length];
            cipherText = Arrays.copyOfRange(input, cryptedIv.length, cryptedIv.length + cipherText.length);

            // decrypt the IV using ECB
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"));
            iv = cipher.doFinal(cryptedIv);

            cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");

            // decrypt the remaining ciphertext in cbc with the decrypted IV
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
            return cipher.doFinal(cipherText);
        } catch (final InvalidKeyException e) {
            e.printStackTrace();
        } catch (final InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (final NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (final NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (final IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (final BadPaddingException e) {
            e.printStackTrace();
        } catch (final NoSuchProviderException e) {
            e.printStackTrace();
        }
        return new byte[0];
    }

    /**
     * Performs the Jenkins hash on an input byte array
     */
    public static byte[] JenkinsHash(byte[] input) {
        final JenkinsHash jHash = new JenkinsHash();
        final long hash = jHash.hash(input);

        final ByteBuffer buffer = ByteBuffer.allocate(4);
        buffer.putInt((int) hash);

        final byte[] array = buffer.array();
        final byte[] output = new byte[array.length];
        for (int i = 0; i < array.length; i++) {
            output[array.length - 1 - i] = array[i];
        }

        return output;
    }

    /**
     * Performs CRC32 on an input byte array using the CrcStandard.Crc32Bit parameters
     */
    public static byte[] CRCHash(byte[] input) {
        final CRC32 crc = new CRC32();
        crc.update(input);
        final long hash = crc.getValue();

        final ByteBuffer buffer = ByteBuffer.allocate(4);
        buffer.putInt((int) hash);

        final byte[] array = buffer.array();
        final byte[] output = new byte[array.length];
        for (int i = 0; i < array.length; i++) {
            output[array.length - 1 - i] = array[i];
        }

        return output;
    }

    /**
     * Performs an Adler32 on the given input
     */
    public static byte[] AdlerHash(byte[] input) {
        int a = 0, b = 0;
        for (final byte element : input) {
            a = (a + element) % 65521;
            b = (b + a) % 65521;
        }
        final ByteBuffer buffer = ByteBuffer.allocate(4);
        buffer.putInt(a | b << 16);
        return buffer.array();
    }

    /**
     * Generate an array of random bytes given the input length
     */
    public static byte[] GenerateRandomBlock(int size) {
        final byte[] block = new byte[size];
        final SecureRandom random = new SecureRandom();
        random.nextBytes(block);
        return block;
    }
}




Java Source Code List

com.kevelbreh.steamchat.SteamChat.java
com.kevelbreh.steamchat.account.AuthenticatorService.java
com.kevelbreh.steamchat.account.Authenticator.java
com.kevelbreh.steamchat.account.SteamAccount.java
com.kevelbreh.steamchat.activity.AuthenticationActivity.java
com.kevelbreh.steamchat.activity.ConversationActivity.java
com.kevelbreh.steamchat.activity.FriendsActivity.java
com.kevelbreh.steamchat.activity.InteractionsActivity.java
com.kevelbreh.steamchat.activity.LauncherActivity.java
com.kevelbreh.steamchat.activity.SettingsActivity.java
com.kevelbreh.steamchat.fragment.ConversationFragment.java
com.kevelbreh.steamchat.fragment.FriendsFragment.java
com.kevelbreh.steamchat.fragment.InteractionsFragment.java
com.kevelbreh.steamchat.fragment.SettingsFragment.java
com.kevelbreh.steamchat.provider.SteamProviderUtils.java
com.kevelbreh.steamchat.provider.SteamProvider.java
com.kevelbreh.steamchat.provider.content.InteractionContentItem.java
com.kevelbreh.steamchat.provider.content.PersonaContentItem.java
com.kevelbreh.steamchat.provider.content.UserContentItem.java
com.kevelbreh.steamchat.steam2.SteamConnection.java
com.kevelbreh.steamchat.steam2.SteamEventBus.java
com.kevelbreh.steamchat.steam2.SteamService.java
com.kevelbreh.steamchat.steam2.handler.ConnectionHandler.java
com.kevelbreh.steamchat.steam2.handler.FriendHandler.java
com.kevelbreh.steamchat.steam2.handler.MessageHandler.java
com.kevelbreh.steamchat.steam2.handler.UserHandler.java
com.kevelbreh.steamchat.steam2.packet.Packet.java
com.kevelbreh.steamchat.steam2.packet.ProtoPacket.java
com.kevelbreh.steamchat.steam.SteamClient.java
com.kevelbreh.steamchat.steam.SteamID.java
com.kevelbreh.steamchat.steam.SteamServiceHandler.java
com.kevelbreh.steamchat.steam.SteamService.java
com.kevelbreh.steamchat.steam.handler2.ConnectionHandler.java
com.kevelbreh.steamchat.steam.handler2.FriendHandler.java
com.kevelbreh.steamchat.steam.handler2.Handler.java
com.kevelbreh.steamchat.steam.handler2.UserHandler.java
com.kevelbreh.steamchat.steam.handler.AEventHandler.java
com.kevelbreh.steamchat.steam.handler.AuthenticationHandler.java
com.kevelbreh.steamchat.steam.handler.FriendsHandler.java
com.kevelbreh.steamchat.steam.handler.IEventHandler.java
com.kevelbreh.steamchat.steam.handler.IHandler.java
com.kevelbreh.steamchat.steam.handler.MessageDebugHandler.java
com.kevelbreh.steamchat.steam.language.Language.java
com.kevelbreh.steamchat.steam.language.Message.java
com.kevelbreh.steamchat.steam.network.TCPConnection.java
com.kevelbreh.steamchat.steam.network.packet.ChannelEncryptRequest.java
com.kevelbreh.steamchat.steam.network.packet.ChannelEncryptResponse.java
com.kevelbreh.steamchat.steam.network.packet.ChannelEncryptResult.java
com.kevelbreh.steamchat.steam.network.packet.ClientLogOnResponse.java
com.kevelbreh.steamchat.steam.network.packet.ClientLogOn.java
com.kevelbreh.steamchat.steam.network.packet.HeartBeat.java
com.kevelbreh.steamchat.steam.network.packet.MultiPacket.java
com.kevelbreh.steamchat.steam.network.packet.Packet.java
com.kevelbreh.steamchat.steam.network.packet.ProtoPacket.java
com.kevelbreh.steamchat.steam.proto.DescriptorsProto.java
com.kevelbreh.steamchat.steam.proto.EncryptedAppTicketProto.java
com.kevelbreh.steamchat.steam.proto.SteamMessagesBaseProto.java
com.kevelbreh.steamchat.steam.proto.SteamMessagesClientServerProto.java
com.kevelbreh.steamchat.steam.security.AsnKeyParser.java
com.kevelbreh.steamchat.steam.security.AsnParser.java
com.kevelbreh.steamchat.steam.security.BerDecodeException.java
com.kevelbreh.steamchat.steam.security.Cryptography.java
com.kevelbreh.steamchat.steam.security.NetEncryption.java
com.kevelbreh.steamchat.steam.security.PublicKey.java
com.kevelbreh.steamchat.steam.security.RSA.java
com.kevelbreh.steamchat.steam.util.BinaryReader.java
com.kevelbreh.steamchat.steam.util.BinaryWriter.java
com.kevelbreh.steamchat.steam.util.BitVector64.java
com.kevelbreh.steamchat.steam.util.JenkinsHash.java
com.kevelbreh.steamchat.util.AServiceActivity.java
com.kevelbreh.steamchat.util.Dump.java
com.kevelbreh.steamchat.util.MiscUtils.java
com.kevelbreh.steamchat.widget.adapter.ChatAdapter.java
com.kevelbreh.steamchat.widget.adapter.ConversationAdapter.java
com.kevelbreh.steamchat.widget.adapter.FriendAdapter.java
com.kevelbreh.steamchat.widget.view.AvatarView.java
com.kevelbreh.steamchat.widget.view.FriendInteractionsView.java