android 应用加密_加密的短信应用程序android

android 应用加密

重点 (Top highlight)

In this tutorial, we’ll build an encrypted chat/messaging example app for Android. To do this, we will combine both Stream Chat and Virgil Security platforms. Stream and Virgil make it easy to build a solution with excellent security by combining all of the features you would expect as a developer when creating a messaging app.

在本教程中,我们将为Android构建一个加密的聊天/消息示例应用程序。 为此,我们将结合Stream ChatVirgil Security平台。 通过结合使用您在创建消息传递应用程序时作为开发人员的所有期望功能,Stream和Virgil可以轻松构建具有出色安全性的解决方案。

These two services allow developers to integrate chat that is zero knowledge to your backend or Stream. The example app embeds Virgil Security’s eThree Kit — a secure encrypted messaging platform — with Stream Chat’s Android components.

这两项服务使开发人员可以将对您零知识的聊天集成到您的后端或流中。 示例应用程序嵌入 维吉尔安全 eThree套件 —安全的加密消息传递平台 -使用Stream Chat的Android组件。

Note that all source code for this example, Android app is available on GitHub. Additionally, before jumping into this tutorial, I recommend checking out the Stream Chat Android tutorial, which will walk you through how to implement Stream Chat from a high-level overview.

请注意,此示例Android应用程序的所有源代码都可以在GitHub找到 。 另外,在进入本教程之前,我建议您阅读AndroidStream Chat教程 ,它将从较高的概述中逐步指导您如何实现Stream Chat。

什么是端到端加密消息? (What Is End-To-End Encrypted Messaging?)

End-to-end encrypted messaging means that the users within that specific chat can only read messages sent between two people. To enable this, the messages that are sent are encrypted before leaving a user’s device, and can only be decrypted by the intended recipient (end-user).

端到端加密消息传递意味着特定聊天中的用户只能阅读两个人之间发送的消息。 为此,发送的消息在离开用户设备之前已加密,并且只能由预期的接收者(最终用户)解密。

Virgil Security is a vendor that allows developers to create end-to-end encryption via public/private key technology through the use of their robust and secure encrypted messaging service. With Virgil’s Android SDK, developers can securely create, store, and provide robust end-to-end encryption.

Virgil Security是一家供应商,允许开发人员通过使用其健壮且安全的加密消息传递服务,通过公用/专用密钥技术创建端到端加密。 借助Virgil的Android SDK,开发人员可以安全地创建,存储和提供强大的端到端加密。

During this tutorial, we will learn how to build a Stream Chat app that uses Virgil’s encryption/decryption platform to prevent anyone except the intended parties from reading messages. No one in your company, nor any cloud provider you use, can read these messages. In essence, even if a malicious person gained access to the database containing the messages, that person would only see encrypted text, called ciphertext.

在本教程中,我们将学习如何构建一个使用Virgil的加密/解密平台的Stream Chat应用程序,以防止除目标用户之外的任何人阅读消息。 您公司中的任何人,或者您使用的任何云提供商,都无法阅读这些消息。 本质上,即使恶意人员获得了访问包含消息的数据库的权限,该人员也只会看到称为密文的加密文本。

构建加密的聊天消息应用程序 (Building an Encrypted Chat Messaging Application)

To build this app, we’ll mostly rely on two libraries, Stream Chat Android and Virgil Security for Kotlin. Our outcome will encrypt text on the device before sending a message. Decryption and verification will both happen in the receiver’s device. Stream’s Messaging API will only see ciphertext, ensuring our user’s data is never seen by anyone else, including us.

要构建此应用,我们将主要依靠两个库,即Stream Chat Android和Virgil Security for Kotlin。 我们的结果将在发送消息之前对设备上的文本进行加密。 解密和验证都将在接收方的设备中进行。 Stream的Messaging API仅能看到密文,以确保包括我们在内的其他任何人都不会看到我们用户的数据。

To accomplish this, the app performs the following steps:

为此,该应用程序执行以下步骤:

  1. A user authenticates with your backend.

    用户向您的后端进行身份验证。
  2. The user’s app requests a Stream auth token and API key from the backend. The Android app creates a Stream Chat Client for that user.

    用户的应用程序从后端请求流身份验证令牌和API密钥。 Android应用会为该用户创建一个Stream Chat Client

  3. The user’s app requests a Virgil auth token from the backend and registers with Virgil. This generates their private and public key. The private key is stored locally, and the public key is stored in Virgil.

    用户的应用程序从后端请求Virgil身份验证令牌,并向Virgil注册。 这将生成其私钥和公钥。 私钥存储在本地,而公钥存储在Virgil中。
  4. Once the user decides who they want to chat with the app creates and joins a Stream Chat Channel.

    用户决定要与该应用聊天的对象后,即可创建并加入流聊天频道

  5. The app asks Virgil for the receiver’s public key.

    该应用程序向Virgil询问接收者的公共密钥。
  6. The user types a message and sends it to Stream. Before sending, the app passes the receiver’s public key to Virgil to encrypt the message. The message is relayed through Stream Chat to the receiver. Stream receives ciphertext, meaning they can never see the original message.

    用户键入一条消息并将其发送到Stream。 在发送之前,该应用将接收者的公钥传递给Virgil来加密消息。 该消息通过流聊天中继到接收者。 Stream收到密文,这意味着他们永远看不到原始消息。
  7. The receiving user decrypts the sent message using Virgil. When the message is received, the app decrypts the message using the Virgil and this is passed along to Stream’s UI components. Virgil verifies the message is authentic by using the sender’s public key.

    接收用户使用Virgil解密发送的消息。 收到消息后,应用程序将使用Virgil对消息进行解密,并将消息传递到Stream的UI组件。 Virgil使用发件人的公钥验证邮件的真实性。

While this looks complicated, Stream and Virgil do most of the work for us. We’ll use Stream’s out of the box UI components to render the chat UI and Virgil to do all of the cryptography and key management. We simply combine these services.

尽管这看起来很复杂,但Stream和Virgil为我们完成了大部分工作。 我们将使用Stream的现成UI组件来呈现聊天UI,而Virgil将使用所有的加密和密钥管理。 我们只是将这些服务结合在一起。

The code is split between the Android frontend contained in the android directory, and the Express (Node.js) backend is found in the backend directory. See the README.md in each directory to see installing and running instructions. If you'd like to follow along with running code, make sure you get both the backend and android running before continuing.

该代码是Android之间的分裂前端包含在android目录,而快递(Node.js的)后端在发现backend目录。 请参阅每个目录中的README.md以查看安装和运行说明。 如果您想继续执行代码,请确保在继续运行之前先运行backendandroid

Let’s walk through and look at the important code needed for each step.

让我们来看一下每个步骤所需的重要代码。

先决条件 (Prerequisites)

Basic knowledge of Android (Kotlin) and Node.js is required to follow this how-to tutorial.

要学习此入门指南,需要具备Android(Kotlin)和Node.js的基础知识。

Note that this secure messaging app is intended only to run locally on your machine, and we will not be covering how to deploy the example app to iOS or Android app stores.

请注意,此安全消息传递应用程序仅旨在在您的计算机上本地运行,我们将不介绍如何将示例应用程序部署到iOS或Android应用程序商店。

We use Anko to simplify our asynchronous code. Please note this library was recently deprecated. There are also likely bugs in our async implementation. However, we chose to keep the noise to a minimum in this tutorial by leveraging Anko and keeping async simple. Please use best practices for asynchronous code.

我们使用Anko来简化异步代码。 请注意,该库最近已弃用 。 我们的异步实现中也可能存在错误。 但是,在本教程中,我们选择通过利用Anko并使异步保持简单来将噪声降至最低。 请对异步代码使用最佳做法。

You will need an account with Stream and Virgil. Once you’ve created your accounts, you can place your credentials in backend/.env if you'd like to run the code. You can use backend/.env.example as a reference for what credentials are required. You also need to place your Stream API key in MainActivity.kt:60.

您将需要具有StreamVirgil的帐户。 创建帐户后,如果您想运行代码,则可以将凭据放在backend/.env 。 您可以使用backend/.env.example作为所需凭据的参考。 您还需要将Stream API密钥放在MainActivity.kt:60

步骤0。设置后端 (Step 0. Setup the Backend)

For our Android frontend to interact with Stream and Virgil, the application provides three endpoints:

为了使我们的Android前端与Stream和Virgil进行交互,该应用程序提供了三个端点:

  • POST /v1/authenticate: This endpoint generates an auth token that allows the Android app to communicate with /v1/stream-credentials and /v1/virgil-credentials. To keep things simple, this endpoint allows the client to be any user. The frontend tells the backend who it wants to authenticate as. In your application, this should be replaced with your API's authentication endpoint.

    POST /v1/authenticate :此端点生成一个auth令牌,该令牌允许Android应用与/v1/stream-credentials/v1/virgil-credentials 。 为简单起见,此端点允许客户端成为任何用户。 前端告诉后端它想作为谁进行身份验证。 在您的应用程序中,应将其替换为您API的身份验证端点。

  • POST /v1/stream-credentials: This returns the data required for the Android app to communicate with Stream. In order return this info we need to tell Stream this user exists and ask them to create a valid auth token:

    POST /v1/stream-credentials :这将返回Android应用程序与Stream通信所需的数据。 为了返回此信息,我们需要告诉Stream该用户存在,并要求他们创建有效的身份验证令牌:

The response payload has this shape:

响应有效负载具有以下形状:

  • apiKey is the stream account identifier for your Stream instance. Needed to identify what account your frontend is trying to connect with.

    apiKey是您的Stream实例的流帐户标识符。 需要确定您的前端试图连接哪个帐户。

  • token JWT token to authorize the frontend with Stream.

    token JWT令牌,用于使用Stream授权前端。

  • user: This object contains the data that the frontend needs to connect and render the user's view.

    user :此对象包含前端连接和呈现用户视图所需的数据。

  • POST /v1/virgil-credentials: This returns the authentication token used to connect the frontend to Virgil. We use the Virgil Crypto SDK to generate a valid auth token for us:

    POST /v1/virgil-credentials :这将返回用于将前端连接到Virgil的身份验证令牌。 我们使用Virgil Crypto SDK为我们生成有效的身份验证令牌:

In this case, the frontend only needs the auth token.

在这种情况下,前端只需要auth令牌。

步骤1.用户通过后端进行身份验证 (Step 1. User Authenticates With Backend)

First, we log in to a user. To keep things simple we’ll just have an empty form that lets you log in with any name:

首先,我们登录到用户。 为简单起见,我们将使用一个空表格来使用任何名称登录:

Image for post

This is a simple form that takes any arbitrary name, effectively allowing us to log in as anyone. We set this up in our MainActivity:

这是一种简单的形式,可以使用任意名称,有效地允许我们以任何人身份登录。 我们在MainActivity

And the layout:

以及布局:

When we submit the form, we sign into our backend, get a Stream and Virgil frontend auth token, generate our private key, and register with Virgil, then start our next activity. We’ll look at each of these in turn.

提交表单时,我们登录到后端,获取Stream和Virgil前端身份验证令牌,生成私钥,并在Virgil中注册,然后开始下一个活动。 我们将依次研究每个。

Let’s see our sign in and token generation:

让我们看看我们的登录和令牌生成:

Since our backend (see Step 1) does the token generation, these are simple REST calls. The tokens returned are frontend auth tokens, which allow our client to talk to Stream and Virgil directly. Besides returning a list of users, we no longer need our backend to do any work.

由于我们的backend (请参阅步骤1)执行令牌生成,因此这些都是简单的REST调用。 返回的令牌是前端身份验证令牌,使我们的客户端可以直接与Stream和Virgil进行对话。 除了返回用户列表之外,我们不再需要后端进行任何工作。

Now that we have our frontend tokens, let’s generate our private keys and register our public keys with Virgil:

现在我们有了前端令牌,让我们生成私有密钥并向Virgil注册我们的公共密钥:

Virgil’s client is called eThree. We initialize an EThree instance and register. This call generates a private key and stores it on the device and sends our public key to Virgil. If we get a RegistrationException, we have already registered this user. Keep in mind, and you cannot log into the same user on a different device since we're not sharing the private key with the other device! This is possible, but out of scope for this tutorial. If you'd like to accomplish this, see Virgil's documentation.

Virgil的客户称为eThree 。 我们初始化一个EThree实例并注册。 该调用将生成一个私钥并将其存储在设备上,并将我们的公钥发送给Virgil。 如果收到RegistrationException ,则我们已经注册了该用户。 请注意,由于我们不与其他设备共享私钥,因此您无法在其他设备上登录同一用户! 这是可能的,但是超出了本教程的范围。 如果您想完成此操作,请参阅Virgil的文档

Now that we have our tokens and registration let’s find a user to chat with!

现在我们有了令牌和注册,让我们找到一个可以聊天的用户!

步骤2:列出使用者 (Step 2: List users)

To keep things simple, we’ll get all registered users from our backend and display them in a simple list view:

为简单起见,我们将从后端获取所有注册用户,并将其显示在简单的列表视图中:

Image for post

Here is the activity:

这是活动:

And the layout:

以及布局:

We make an API call via BackendService.getUsers and filter the logged-in user out. We add the response to a simple ArrayAdapter and display our results in a ListView. When a user clicks on a list item, we start a ChannelActivity, which is a 1:1 chat channel.

我们通过BackendService.getUsers进行API调用,并过滤掉登录的用户。 我们将响应添加到简单的ArrayAdapter并将结果显示在ListView 。 当用户单击列表项时,我们将启动ChannelActivity ,这是一个1:1聊天频道。

步骤3:建立私人1:1频道 (Step 3: Create a Private 1:1 Channel)

First, we need to create our channel for our private chat. Let’s look at our activity and layout:

首先,我们需要为我们的私人聊天创建频道。 让我们看看我们的活动和布局:

And the layout:

以及布局:

We use off the shelf Stream UI components with two slight variations. First, we hook in a custom EncryptedMessageInputView, which allows us to encrypt a message before sending it. We also hook in a custom EncryptedMessageViewHolderFactory, which allows message decryption (we'll look at this in a bit). The essential bits start inside of doAsync. First, we look up the other user's public key. This let's use encrypt our messages and verify their messages are authentic. Next, we create a channel in Stream via .query. Once then channel is created, we load messages. Before we look at how we load messages, we need to send a message first.

我们使用现成的Stream UI组件有两个微小的变化。 首先,我们挂钩一个自定义的EncryptedMessageInputView ,它允许我们在发送消息之前对其进行加密。 我们还挂钩了一个自定义的EncryptedMessageViewHolderFactory ,它允许消息解密(稍后我们将对此进行介绍)。 基本位在doAsync内部开始。 首先,我们查找其他用户的公钥。 让我们使用加密消息并验证其消息是真实的。 接下来,我们通过.query在Stream中创建一个通道。 创建通道后,我们便会加载消息。 在查看如何加载消息之前,我们需要先发送一条消息。

步骤4:发送加密的消息 (Step 4: Sending an Encrypted Message)

Let’s look at EncryptedMessageInputView, which is bound in the layout and configured in our activity. Here is the code:

让我们看一下EncryptedMessageInputView ,它绑定在布局中并在我们的活动中配置。 这是代码:

We override Stream’s MessageInputView and simply decrypt the message before sending it. MessageInputView calls prepareMessage before sending it to the API, so we override this and encrypt before sending the message along.

我们重写Stream的MessageInputView并在发送之前简单地解密消息。 MessageInputView在将其发送到API之前会调用prepareMessage ,因此我们将其覆盖并加密,然后再发送消息。

Please note that updating a message does not utilize this method, so be aware if you want to support edit functionality. You can consider building your own MessageInputView. For brevity, we won't go there in this tutorial.

请注意,更新消息不会使用此方法,因此请注意是否要支持编辑功能。 您可以考虑构建自己的MessageInputView 。 为简便起见,本教程中不会去那里。

步骤5:查看消息 (Step 5: Viewing Messages)

Since all of our messages in Stream our now ciphertext, we need to decrypt them before displaying. To hook into Stream’s UI components, we bind via binding.messageList.setViewHolderFactory(EncryptedMessageViewHolderFactory(eThree)). With our custom factory, we can initialize a custom decryption object for each message:

由于我们Stream中的所有消息都是我们现在的密文,因此我们需要在显示之前解密它们。 为了连接到Stream的UI组件,我们通过binding.messageList.setViewHolderFactory(EncryptedMessageViewHolderFactory(eThree))绑定。 使用我们的自定义工厂,我们可以为每条消息初始化一个自定义解密对象:

This factory checks if we have a message type (vs. another type such as a date separator) and initializes our EncryptedMessageViewHolder. Let's look take a look:

该工厂检查我们是否具有消息类型(相对于其他类型,例如日期分隔符),并初始化EncryptedMessageViewHolder 。 让我们看一下:

First, we check if we have a regular message, and if we do, we decrypt it. We copy our message object to avoid mutating the original version (Stream caches this, and we’ll mess things up if we manipulate that). With that copy, we check if the message is ours or theirs. In our case, we know how to decrypt directly since we created it. If it’s theirs, we need to look up their public key to verify the message. We pass this to Virgil and do our decryption.

首先,我们检查是否有常规消息,如果有,则将其解密。 我们复制消息对象以避免更改原始版本(Stream对此进行缓存,如果对其进行操作,将会使事情搞砸)。 使用该副本,我们检查邮件是我们的还是他们的。 在我们的案例中,自创建以来,我们就知道如何直接解密。 如果是他们的,我们需要查找他们的公钥以验证消息。 我们将此传递给Virgil并进行解密。

Putting these last steps together, we’ll see our final product:

将这些最后的步骤放在一起,我们将看到最终产品:

Image for post

最后的想法 (Final Thoughts)

And that’s it. We now have a private and extremely secure end-to-end encrypted messaging app built for Android with Stream Chat and Virgil Security. You should have a full understanding of the basics of end-to-end encryption using Stream Chat and Virgil Security, along with a fundamental understanding of how the E2EE process works when implemented with Android, Virgil, and Stream Chat.

就是这样。 w ^ e现在拥有一个专用于Android的私有且极其安全的端到端加密消息应用程序,具有 即时通讯 维吉尔安全 您应该全面了解使用Stream Chat和Virgil Security进行的端到端加密的基础知识,以及对在使用Android,Virgil和Stream Chat实施时E2EE流程如何工作的基本理解。

If you want to take it a step further, Stream Chat offers several resources to help you get to the next level with your Android chops. Check out the links below:

如果您想更进一步,Stream Chat提供了多种资源来帮助您将Android排行榜提升到一个新的水平。 检查下方的链接:

Happy coding, and as always, please feel free to drop any thoughts or questions in the comments below.

祝您编程愉快,并且一如既往,请随时在下面的评论中提出任何想法或问题。

Originally published on The Stream Blog at https://getstream.io/blog/encrypted-messaging-app-android/.

最初发布在The Stream Blog上, 网址 https://getstream.io/blog/encrypted-messaging-app-android/

翻译自: https://medium.com/swlh/encrypted-messaging-app-android-c57f14a180cb

android 应用加密

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值