вторник, 26 февраля 2013 г.

RSA-шифрование в Android (Java)

В одном своём проекте я решил реализовать безопасную переписку между двумя пользователями используя мобильное приложение на Android.
Задача сводилась к тому, чтобы пользователь мог создать себе пару ключей (публичный/приватный), иметь возможность сохранить их в виде Base64-строки (для передачи по http и простого хранения в виде текстовой строки), а также чтобы можно было восстановить эти ключи, сохранённые в Base64 и использовать их для шифрования.


Пример использования класса Crypto (Я-Alex, у меня есть пара ключей public/private; Ustas-мой собеседник, передающий сообщение мне)

Юстас - Алексу
--------------
на стороне Юстаса (необходимо предварительно получить открытый(публичный) ключ Алекса):
Crypto Ustas = new Crypto();
Ustas.GenerateKeys();
String toAlex = Ustas.RSAEncrypt("Привет!", Alex.publicBase64);

на стороне Алекса:
Crypto Alex = new Crypto();
Alex.GenerateKeys();
String fromUstas = Alex.RSADecrypt(toAlex, Alex.privateBase64);


класс Crypto.java:
------------------
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import android.util.Base64;
import android.util.Log;

public class Crypto
{
    KeyPairGenerator kpg;
    KeyPair kp ;
    int keySize = 1024;
    RSAPublicKey key;

    public String publicBase64;
    public String privateBase64;
   
    public void GenerateKeys() throws NoSuchAlgorithmException
    {
        kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024);
        kp = kpg.genKeyPair();
        PublicKey publicKey = kp.getPublic();
        PrivateKey privateKey = kp.getPrivate();

        byte[] publicBytes = publicKey.getEncoded();
        publicBase64 = Base64.encodeToString(publicBytes, Base64.DEFAULT);

        byte[] privateBytes = privateKey.getEncoded();
        privateBase64 = Base64.encodeToString(privateBytes, Base64.DEFAULT);
    }
   
    public String RSAEncrypt(final String plain, String publicKeyBase64) throws NoSuchAlgorithmException, NoSuchPaddingException,
        InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException {
       
        PublicKey publicKey;
        byte[] publicBytes = Base64.decode(publicKeyBase64, Base64.DEFAULT);
        publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicBytes));

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(plain.getBytes());

        String encrypted = Base64.encodeToString(encryptedBytes, Base64.DEFAULT);
        return encrypted;
    }

    public String RSADecrypt(final String encrypted, String privateKeyBase64) throws NoSuchAlgorithmException, NoSuchPaddingException,
        InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException {
   
        byte[] privateBytes = Base64.decode(privateKeyBase64, Base64.DEFAULT);
        PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateBytes));
       
        byte[] encryptedBytes = Base64.decode(encrypted, Base64.DEFAULT);
        Cipher cipher1 = Cipher.getInstance("RSA");
        cipher1.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher1.doFinal(encryptedBytes);
        String decrypted = new String(decryptedBytes);
        return decrypted;
    }
   
}

Как выложить свой проект на github

I. Подготовка
    1. Зарегистрироваться на github
    2. Создать проект
    3. Установить git

II.
1.
github: new repository
git config --global user.name "my_username"
git config --global user.email "my@email.com"
git config --global core.autocrlf true
git config --global core.safecrlf true

2. Устанавливаем TortoiseGit
3. На папке проекта ПКМ - Add... и добавляем все файлы проекта в репозиторий.
4. Выполняем команды (ПКМ на папке проекта - Git Bash Here):

$ git remote add origin https://github.com/my_username/my_project.git
$ git push -u origin master