Java 如何在Android中加密/解密发送/接收的消息?

Java 如何在Android中加密/解密发送/接收的消息?,java,android,encryption,rsa,privacy,Java,Android,Encryption,Rsa,Privacy,我们正在构建一个聊天客户端(如Whatsapp等),用于发送和接收私人消息。为了隐私起见,我们决定在消息到达和发送时对其进行加密和解密 我想我们可以使用RSA私钥和公钥进行加密。我知道我们通常需要两对钥匙,一对在服务器上,一对在电话上。这就引出了我在这里要问的一些问题 如何在android中生成密钥对 它们应该如何储存 服务器和客户端上的每个用户都需要不同的密钥对吗 请随意添加任何有用的信息,因为我是一个完全的安全新手。有许多加密/解密算法,如数据加密标准(DES)、Playfair等。 你可以

我们正在构建一个聊天客户端(如Whatsapp等),用于发送和接收私人消息。为了隐私起见,我们决定在消息到达和发送时对其进行加密和解密

我想我们可以使用RSA私钥和公钥进行加密。我知道我们通常需要两对钥匙,一对在服务器上,一对在电话上。这就引出了我在这里要问的一些问题

  • 如何在android中生成密钥对
  • 它们应该如何储存
  • 服务器和客户端上的每个用户都需要不同的密钥对吗

  • 请随意添加任何有用的信息,因为我是一个完全的安全新手。

    有许多加密/解密算法,如数据加密标准(DES)、Playfair等。 你可以用那些。如果你愿意,做你自己的算法。我曾经制作过一个messenger应用程序,并制作了自己的加密/解密算法


    您也可以选择使用对称或非对称密钥算法。。。继续工作,信使有一个很好的范围:)

    有许多加密/解密算法,如数据加密标准(DES)、Playfair等。 你可以用那些。如果你愿意,做你自己的算法。我曾经制作过一个messenger应用程序,并制作了自己的加密/解密算法


    您也可以选择使用对称或非对称密钥算法。。。继续工作,信使有一个很好的范围:)

    > P>你需要一个中央服务器,它为每个用户提供证书来验证用户(否则你将永远容易受到中间人攻击)。因此,对于两个用户(Joe和Sally),将有三个证书:1)验证中央服务器的证书,2)验证Joe的证书,3)验证Sally的证书

    因此,当Joe想要与Sally开始沟通时,应发生以下情况:

  • Joe从中央服务器请求Sally的公钥
  • Joe通过服务器的公钥(通过检查数字证书)对服务器进行身份验证
  • Joe使用服务器的公钥加密共享密钥,然后将加密的共享密钥发送到服务器
  • 只有服务器可以解密Joe的共享密钥,从而使用该共享密钥加密(通过)Sally的公钥,并将Sally的公钥(通过Joe建议的共享密钥加密)发送给Joe
  • 乔现在拥有萨利的公钥;已验证,因为它来自已验证的服务器
  • Joe向Sally发送一个请求,请求发起通信,将自己标识为“Joe”,并附上数字证书
  • Sally通过中央服务器验证“Joe”
  • Sally检索Joe的公钥的方式与Joe从中央服务器获取Sally的公钥的方式相同
  • 萨莉给乔发了一把共享密钥
  • Sally使用Joe的公钥对多部分消息进行加密,其中包括1)共享密钥和2)使用Sally的私钥加密的数字证书。
  • Joe收到Sally的加密消息(只有Joe可以解密,因为它是用Joe的公钥加密的)
  • Joe解密消息并接收Sally提议的共享密钥
  • Joe收到Sally的数字证书,用Joe的公钥加密,并尝试用之前从中央服务器获得的Sally公钥解密
  • 如果Joe成功解密了数字证书,那么Joe可以确信Sally是提出共享密钥的人
  • Joe使用共享密钥通过对称加密向Sally发送共享密钥确认
  • Sally通过Sally提议的共享密钥接收Joe的确认
  • Sally和Joe现在可以通过Sally最初提出的共享密钥使用对称加密技术来回通信
  • 那么,为什么所有这些都是必要的呢?首先,您需要一个“受信任的”代理(即中央服务器)。否则你永远无法确定你在和谁交流。你可能会问:为什么Sally需要签署她的共享密钥,而只有Joe可以解密它(如果Sally使用Joe的公钥加密)?原因是任何人都可以通过Joe的公钥加密共享密钥!因此,如果乔接收到一个未签名的共享密钥,他可能会开始与中间的人通信,他只是使用乔的公钥生成共享密钥。正如Sally需要确认Joe是试图与她通信的实际实体一样,Joe需要确保他收到的共享密钥实际上来自Sally(因此她需要使用私钥签名)

    RSA不安全!!!如果有足够的通信量,就可以解密由RSA编码的消息。因此,您应该有一个协议,用于定期更新用于身份验证的公钥/私钥。这对于用户来说很简单:您的中央服务器将保存每个用户的公钥。服务器应定期请求每个用户生成新的私钥/公钥对,并将公钥发送到服务器进行更新(此通信可通过每个用户使用的以前私钥/公钥完成)

    对于中央服务器本身来说,这有点“困难”。如果您的中央服务器希望更改其私钥/公钥(对服务器进行身份验证),则它需要与每个用户通信,以使每个用户都知道更改。当用户更改其私钥/公钥时,这是一对一的通信(仅在用户和服务器之间),但当服务器想要更改其私钥/公钥时,它必须与所有用户通信

    注意事项:

    我并不认为我上面提出的是“规范”模式。我所说的是
    public class Constants {
    
    // encryption/decryption
    public static String AES_KEY = "0366D8637F9C6B21";      
    public static byte[] IV_VECTOR = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    
    }
    
    
    
    /**
     * This class is used to decrypt an encrypted string value.
     * 
     * @author kthakur
     *
     */
    public class EncryptDecrytData {
    
    
        /**
         * This method is used to encrypt a string value.
         * 
         * @param text
         *          - string value to be encrypted.
         *          
         * @return result(encrypted string) as String
         * 
         * @throws Exception
         * 
         */
        @TargetApi(8)
        public static String encrytData(String text) throws Exception {
    
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            byte[] static_key = Constants.AES_KEY.getBytes();
    
            SecretKeySpec keySpec = new SecretKeySpec(static_key, "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(Constants.IV_VECTOR);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
    
            byte[] results = cipher.doFinal(text.getBytes());
    
            String result = Base64.encodeToString(results, Base64.NO_WRAP|Base64.DEFAULT);
            return result;
    
        }
    
        /**
         * This method is used to decrypt a string value.
         * 
         * @param text
         *          - string value to be decrypted.
         * @return result(decrypted string) as String
         * 
         * @throws Exception
         */
        @SuppressLint("NewApi")
        public static String decryptData(String text)throws Exception{
    
            byte[] encryted_bytes = Base64.decode(text, Base64.DEFAULT);
    
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            byte[] static_key = Constants.AES_KEY.getBytes();
    
            SecretKeySpec keySpec = new SecretKeySpec(static_key, "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(Constants.IV_VECTOR);
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
    
            byte[] decrypted = cipher.doFinal(encryted_bytes);
            String result = new String(decrypted);
    
            return result;
        }
    }