Шифрование текстовых сообщений от начала до конца с использованием AES - PullRequest
0 голосов
/ 22 декабря 2018

Сквозное шифрование в Android.Я пытаюсь реализовать приложение чата в Android.

Я пробовал алгоритмы AES для шифрования и дешифрования, успешно сгенерировал закрытый и открытый ключ

GenerateRsaKeyPair.java класс, который генерирует публичный и приватныйпопытка ключа {

        // 1. generate public key and private key


            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(1024); // key length
            KeyPair keyPair = keyPairGenerator.genKeyPair();
            String privateKeyString = Base64.encodeToString(keyPair.getPrivate().getEncoded(), Base64.DEFAULT);
            publicKeyString = Base64.encodeToString(keyPair.getPublic().getEncoded(), Base64.DEFAULT);

            // 2. print both keys
            System.out.println("rsa key pair generated\n");
            Log.e("privateKey",  privateKeyString );
            Log.e("publicKey",  publicKeyString );
            isgenerated=false;




    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }

этот код зашифровывает сообщение попытаться {

               // 1. generate secret key using AES
               KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
               keyGenerator.init(128); // AES is currently available in three key sizes: 128, 192 and 256 bits.T
               // the design and strength of all key lengths of the AES algorithm are sufficient to protect classified information up to the SECRET level
               SecretKey secretKey = keyGenerator.generateKey();
               plainText=editTextsend.getText().toString();

               // 2. get string which needs to be encrypted // our case message
               String text = plainText;//"<your_string_which_needs_to_be_encrypted_here>"
               Log.e("string",text);

               // 3. encrypt string using secret key
               byte[] raw = secretKey.getEncoded();
               SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
               Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//PKCS5Padding
               cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));
               String cipherTextString = Base64.encodeToString(cipher.doFinal(text.getBytes(Charset.forName("UTF-8"))), Base64.DEFAULT);
               Log.e("ciphertext",cipherTextString);
               // 4. get public key
               X509EncodedKeySpec publicSpec = new X509EncodedKeySpec(Base64.decode(publicKeyString, Base64.DEFAULT));
               KeyFactory keyFactory = KeyFactory.getInstance("RSA");
               PublicKey publicKey = keyFactory.generatePublic(publicSpec);

               // 6. encrypt secret key using public key
               Cipher cipher2 = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
               cipher2.init(Cipher.ENCRYPT_MODE, publicKey);
               String encryptedSecretKey = Base64.encodeToString(cipher2.doFinal(secretKey.getEncoded()), Base64.DEFAULT);
               Log.e("encryptedSecretKey",encryptedSecretKey);

               // 7. pass cipherTextString (encypted sensitive data) and encryptedSecretKey to your server via your preferred way.
               // Tips:
               // You may use JSON to combine both the strings under 1 object.
               // You may use a volley call to send this data to your server.

           } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException | InvalidAlgorithmParameterException e) {
               e.printStackTrace();
           }

этот код успешно расшифровывает сообщение попытаться {

        // 1. Get private key
        PKCS8EncodedKeySpec privateSpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey, Base64.DEFAULT));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(privateSpec);
        Log.e("secretKey",privateKey+"");
        // 2. Decrypt encrypted secret key using private key
        Cipher cipher1 = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
        cipher1.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] secretKeyBytes = cipher1.doFinal(Base64.decode(encryptedSecretKeyString, Base64.DEFAULT));
        SecretKey secretKey = new SecretKeySpec(secretKeyBytes, 0, secretKeyBytes.length, "AES");
        Log.e("secretKey",secretKey+"");
        // 3. Decrypt encrypted text using secret key
        byte[] raw = secretKey.getEncoded();
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));
        byte[] original = cipher.doFinal(Base64.decode(encryptedTextString, Base64.DEFAULT));
        String text = new String(original, Charset.forName("UTF-8"));
        Log.e("text",text);
        // 4. Print the original text sent by client
        System.out.println("text\n" + text + "\n\n");


    } catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }

Я ожидаю, чтомой закрытый ключ и открытый ключ должны быть одинаковыми для конкретного пользователя, но в моем коде, когда я создаю свое приложение, он каждый раз генерировал разные закрытый и открытый ключи, поэтому как бы я управлял текущим пользователем предыдущими сообщениями чата и данными и этим каждый раздля чата и группового чата.Любой ответ и предложение будут заметны.

1 Ответ

0 голосов
/ 24 декабря 2018

Храните свой закрытый ключ в KeyStore, желательно в системном хранилище ключей для дополнительной защиты.Для Android начните, например, с чтения этой официальной статьи о системах хранилищ ключей Android (так как это может также повлиять на генерацию пары ключей).Хранение вашего двоичного закрытого ключа, закодированного в PKCS # 8, в постоянном хранилище («диск»), конечно, также возможно, но хранение ключей без защиты не рекомендуется.Пароль, хранящийся в приложении, является абсолютным минимумом безопасности, который может быть предоставлен;обычно вы пытаетесь нацелиться выше.

Ваш открытый ключ можно просто закодировать с помощью getEncoded.Затем вы можете использовать KeyFactory с алгоритмом "RSA" для получения открытого ключа.Этот открытый ключ обычно кодируется как объект X509SubjectPublicKeyInfo.Конечно, X.509 является подсказкой к спецификациям сертификата X.509 : ключ кодируется в совместимом двоичном формате.Открытые ключи не нуждаются в такой защите, если они могут быть доверенными ;Конечно, злоумышленники не могут заменить их своими открытыми ключами.

Как доверять открытому ключу - тема целых книг по управлению ключами.Для асимметричных ключей вы обычно используете PKI - инфраструктуру открытых ключей - для распространения и проверки статуса ключей, заключенных в открытый ключ сертификаты .Когда для этого используются сертификаты X.509, то PKI часто называют PKIX;сертификаты TLS в вашем браузере являются частью очень большой системы PKIX.

...