Raspberry Pi 2与Windows 10 IoT之间的加密通信

在当今的数字化世界中,数据安全变得越来越重要。无论是在个人项目还是在企业环境中,确保数据在传输过程中的安全性都是一个关键的考虑因素。本文将介绍如何使用C#UWP(Universal Windows Platform)在Raspberry Pi 2(作为服务器)和Windows 10 PC(作为客户端)之间建立加密通信。

UWP是微软推出的一种新型项目类型,它允许应用程序在任何Windows平台上运行,无需任何修改。这包括Windows 8或更高版本、Xbox、Windows Phone等。此外,UWP应用程序现在有一个“清单”文件,如果未在清单中授予权限,应用程序将无法正常工作。

Windows 10 IoT Core是Windows 10的一个版本,专为小型设备优化,无论是否带显示屏。截至本文撰写时,Windows 10 IoT Core支持以下设备:

可以使用UWP为Windows 10 IoT Core开发应用程序。

项目要求

要完成这个项目,需要:

  • Visual Studio 2015
  • Windows 10 IoTSDK
  • 安装了Windows 10 IoT Core的Raspberry Pi2(通过以太网连接;如果使用Wi-Fi,调试和部署可能会遇到问题)

这个项目包含两个解决方案,一个用于Raspberry Pi,另一个用于Windows应用程序。如果有一个解决方案和两个项目,可能会在调试时遇到问题,因为Raspberry Pi使用ARM架构,而PC使用x86架构。

使用代码

在本文中,将使用对称算法来加密和解密数据。以下是加密和解密数据所需的步骤:

  1. 创建一个SymmetricKeyAlgorithmProvider,它有一个静态方法来创建,可以通过传递算法的名称来调用它。
  2. 生成密钥的哈希值。
  3. 将文本转换为二进制。
  4. 使用密钥、二进制文本和IV(初始化向量,可以为null)进行加密。

在本文中,使用了加密密钥"123"。

public static byte[] Encrypt(string text, string passPhrase) { IBuffer iv = null; var symetric = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7); IBuffer keyBuffer = Hash(passPhrase); CryptographicKey key = symetric.CreateSymmetricKey(keyBuffer); IBuffer data = CryptographicBuffer.ConvertStringToBinary(text, BinaryStringEncoding.Utf8); return CryptographicEngine.Encrypt(key, data, iv).ToArray(); } public static string Decrypt(IBuffer data, string passPhrase) { IBuffer iv = null; var symetric = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7); IBuffer keyBuffer = Hash(passPhrase); CryptographicKey key = symetric.CreateSymmetricKey(keyBuffer); IBuffer bufferDecrypted = CryptographicEngine.Decrypt(key, data, iv); return CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, bufferDecrypted); } public static IBuffer Hash(string text) { var hash = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5); CryptographicHash cryptographicHash = hash.CreateHash(); IBuffer data = CryptographicBuffer.ConvertStringToBinary(text, BinaryStringEncoding.Utf8); cryptographicHash.Append(data); return cryptographicHash.GetValueAndReset(); }

服务器TCP

ServerTcp类负责绑定并监听任何端口。在这个例子中,绑定了端口9000。要绑定任何端口,需要在Package.appmanifest -> Capabilities -> Internet(Client & Server)中标记标志。

public async void StartAsync() { try { _cancel = new CancellationTokenSource(); _listener = new StreamSocketListener(); _listener.ConnectionReceived += Listener_ConnectionReceived; await _listener.BindServiceNameAsync(_port.ToString()); } catch (Exception e) { InvokeOnError(e.Message); } } private async void Listener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) { _socket = args.Socket; var reader = new DataReader(args.Socket.InputStream); try { while (!_cancel.IsCancellationRequested) { byte[] data = await ReciveData(reader); IBuffer buffer = data.AsBuffer(); string text = Cryptographic.Decrypt(buffer, "123"); InvokeOnDataRecive(text); } } catch (Exception e) { InvokeOnError(e.Message); } } private async Task ReciveData(DataReader reader) { uint sizeFieldCount = await reader.LoadAsync(sizeof(uint)); if (sizeFieldCount != sizeof(uint)) throw new Exception("Disconnect"); uint bufferSize = reader.ReadUInt32(); uint dataRecive = await reader.LoadAsync(bufferSize); if (dataRecive != bufferSize) throw new Exception("Disconnect"); var data = new byte[bufferSize]; reader.ReadBytes(data); return data; } public async Task SendAsync(string text) { try { var writer = new DataWriter(_socket.OutputStream); byte[] data = Cryptographic.Encrypt(text, "123"); writer.WriteInt32(data.Length); writer.WriteBytes(data); await writer.StoreAsync(); await writer.FlushAsync(); } catch (Exception e) { InvokeOnError(e.Message); } }

Raspberry Pi上启动应用程序

当创建了后台应用程序项目(IoT)时,Visual Studio会创建一个StartUpTask类,应用程序将从该类中的Run方法开始运行。

public void Run(IBackgroundTaskInstance taskInstance) { BackgroundTaskDeferral background = taskInstance.GetDeferral(); var server = new ServerTcp(9000); server.OnError += Server_OnError; server.OnDataRecive += Server_OnDataRecive; ThreadPool.RunAsync(x => { server.StartAsync(); }); }

客户端

public async Task ConnectAsync(string ip, int port) { Ip = ip; Port = port; try { var hostName = new HostName(Ip); _socket = new StreamSocket(); _socket.Control.KeepAlive = true; await _socket.ConnectAsync(hostName, Port.ToString()); _cancel = new CancellationTokenSource(); _writer = new DataWriter(_socket.OutputStream); ReadAsync(); } catch (Exception ex) { InvokeOnError(ex.Message); } } private async Task ReadAsync() { _reader = new DataReader(_socket.InputStream); try { while (!_cancel.IsCancellationRequested) { byte[] data = await ReciveData(_reader); IBuffer buffer = data.AsBuffer(); string text = Cryptographic.Decrypt(buffer, "123"); InvokeOnDataRecive(text); } } catch (Exception e) { InvokeOnError(e.Message); } } public async Task DisconnectAsync() { try { _cancel.Cancel(); _reader.DetachStream(); _reader.DetachBuffer(); _writer.DetachStream(); _writer.DetachBuffer(); await _socket.CancelIOAsync(); _cancel = new CancellationTokenSource(); } catch (Exception ex) { InvokeOnError(ex.Message); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485