在将数据发送到Firebase数据库之前如何对其进行加密? [英] How to encrypt data before sending it to Firebase database?

查看:85
本文介绍了在将数据发送到Firebase数据库之前如何对其进行加密?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Firebase实时数据库制作一个聊天应用程序.我知道Firebase是非常安全的(只要您的规则正确),但是我自己可以使用我的应用程序阅读人们的所有聊天记录.

I am making a chat application using Firebase realtime database. I know that Firebase is very secure(provided your rules are correct), but I myself can read all the chats of the people using my app.

我想停止此操作,为此,我需要一种解密和加密方法.我尝试使用Caesar的解密,但是在此过程中失败了.

I want to stop this, and for this I'd need a decryption and encryption method. I tried using Caesar's decryption but failed in the process.

String encrypt(String talk, int key){

  for(int i=0;i<talk.length;i++)
  //can't think of how to proceed from here

我想知道是否有一种方法可以在这里实现凯撒的加密,或者如果没有,我应该使用哪种其他加密?

I want to know if there's a way to implement Caesar's encryption in here, or if not, which other encryption should I use?

推荐答案

凯撒密码实际上不是密码",也不是对单词的任何加密.它实际上是25种不同编码的集合.根据定义,编码不是加密的,也不安全.如果您正在寻找用于生产的解决方案,那么Caesar Cipher绝对不是.破坏微不足道,根本不提供安全性.

The Caesar Cipher is not actually a "cipher" nor encryption in any use of the word. It is actually a set of 25 different encodings. An encoding, by definition, is not encryption and is not secure. If you're searching for a solution to use in production, the Caesar Cipher is definitely not it. It is trivial to break and provides no security at all.

应该应该做的是清楚地定义自己所保护的威胁模型和攻击媒介.从这里开始,您应该咨询具有实际加密经验的人,以设计出解决所发现问题的方法.

What you should do is clearly define the threat model and attack vectors that you are protecting yourself from. From here, you should consult with someone who has actual cryptography experience to design a solution to the problems you've found.

尽管您可能不会这样做,但没人会这样做,因为他们认为他们更了解.如果您决定不这样做,则至少要花一些时间来学习一些基本的密码学概念.

You probably won't do that though, no one ever does, they think they know better. In the case that you decide to not do that, at the very least, take the time to learn some basic cryptography concepts.

这是我的此处自己的存储库中的一些Java代码,展示了一种安全方法给定密码加密和解密字符串的方法:

Here is some Java code, from my own repository here, that demonstrates a secure method of encrypting and decrypting strings with a given password:

public class SecureCompatibleEncryptionExamples {

private final static String ALGORITHM_NAME = "AES/GCM/NoPadding";
private final static int ALGORITHM_NONCE_SIZE = 12;
private final static int ALGORITHM_TAG_SIZE = 128;
private final static int ALGORITHM_KEY_SIZE = 128;
private final static String PBKDF2_NAME = "PBKDF2WithHmacSHA256";
private final static int PBKDF2_SALT_SIZE = 16;
private final static int PBKDF2_ITERATIONS = 32767;

public static String encryptString(String plaintext, String password) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
    // Generate a 128-bit salt using a CSPRNG.
    SecureRandom rand = new SecureRandom();
    byte[] salt = new byte[PBKDF2_SALT_SIZE];
    rand.nextBytes(salt);

    // Create an instance of PBKDF2 and derive a key.
    PBEKeySpec pwSpec = new PBEKeySpec(password.toCharArray(), salt, PBKDF2_ITERATIONS, ALGORITHM_KEY_SIZE);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(PBKDF2_NAME);
    byte[] key = keyFactory.generateSecret(pwSpec).getEncoded();

    // Encrypt and prepend salt.
    byte[] ciphertextAndNonce = encrypt(plaintext.getBytes(StandardCharsets.UTF_8), key);
    byte[] ciphertextAndNonceAndSalt = new byte[salt.length + ciphertextAndNonce.length];
    System.arraycopy(salt, 0, ciphertextAndNonceAndSalt, 0, salt.length);
    System.arraycopy(ciphertextAndNonce, 0, ciphertextAndNonceAndSalt, salt.length, ciphertextAndNonce.length);

    // Return as base64 string.
    return Base64.getEncoder().encodeToString(ciphertextAndNonceAndSalt);
}

public static String decryptString(String base64CiphertextAndNonceAndSalt, String password) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException {
    // Decode the base64.
    byte[] ciphertextAndNonceAndSalt = Base64.getDecoder().decode(base64CiphertextAndNonceAndSalt);

    // Retrieve the salt and ciphertextAndNonce.
    byte[] salt = new byte[PBKDF2_SALT_SIZE];
    byte[] ciphertextAndNonce = new byte[ciphertextAndNonceAndSalt.length - PBKDF2_SALT_SIZE];
    System.arraycopy(ciphertextAndNonceAndSalt, 0, salt, 0, salt.length);
    System.arraycopy(ciphertextAndNonceAndSalt, salt.length, ciphertextAndNonce, 0, ciphertextAndNonce.length);

    // Create an instance of PBKDF2 and derive the key.
    PBEKeySpec pwSpec = new PBEKeySpec(password.toCharArray(), salt, PBKDF2_ITERATIONS, ALGORITHM_KEY_SIZE);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(PBKDF2_NAME);
    byte[] key = keyFactory.generateSecret(pwSpec).getEncoded();

    // Decrypt and return result.
    return new String(decrypt(ciphertextAndNonce, key), StandardCharsets.UTF_8);
}

public static byte[] encrypt(byte[] plaintext, byte[] key) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
    // Generate a 96-bit nonce using a CSPRNG.
    SecureRandom rand = new SecureRandom();
    byte[] nonce = new byte[ALGORITHM_NONCE_SIZE];
    rand.nextBytes(nonce);

    // Create the cipher instance and initialize.
    Cipher cipher = Cipher.getInstance(ALGORITHM_NAME);
    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(ALGORITHM_TAG_SIZE, nonce));

    // Encrypt and prepend nonce.
    byte[] ciphertext = cipher.doFinal(plaintext);
    byte[] ciphertextAndNonce = new byte[nonce.length + ciphertext.length];
    System.arraycopy(nonce, 0, ciphertextAndNonce, 0, nonce.length);
    System.arraycopy(ciphertext, 0, ciphertextAndNonce, nonce.length, ciphertext.length);

    return ciphertextAndNonce;
}

public static byte[] decrypt(byte[] ciphertextAndNonce, byte[] key) throws InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
    // Retrieve the nonce and ciphertext.
    byte[] nonce = new byte[ALGORITHM_NONCE_SIZE];
    byte[] ciphertext = new byte[ciphertextAndNonce.length - ALGORITHM_NONCE_SIZE];
    System.arraycopy(ciphertextAndNonce, 0, nonce, 0, nonce.length);
    System.arraycopy(ciphertextAndNonce, nonce.length, ciphertext, 0, ciphertext.length);

    // Create the cipher instance and initialize.
    Cipher cipher = Cipher.getInstance(ALGORITHM_NAME);
    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(ALGORITHM_TAG_SIZE, nonce));

    // Decrypt and return result.
    return cipher.doFinal(ciphertext);
}

}

这篇关于在将数据发送到Firebase数据库之前如何对其进行加密?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆