解密 Base64 编码的 RabbitMQ 消息
Decrypt Base64-encoded RabbitMQ message
我正在使用 MassTransit 3.4 和 EncryptedSerializer。消息由我的应用程序正确加密和解密,但现在我希望能够解码出现在 RabbitMQ“_error”队列中的 base64 编码消息。我想编写一些程序来允许用户发现 base64 编码和加密消息的内容,但我正在努力正确解码消息。
这是我到目前为止所做的。 Copy/paste 将 RabbitMQ 管理中的 "Payload" 位 UI 放入我的文本编辑器并尝试 运行 编码为 Convert.FromBase64String(text),然后将字节数组传递给像one found here这样的解密函数。这几乎有效——我以纯文本形式看到了有效载荷的大部分字符,但许多字符都被弄乱了。我无法共享整个消息有效负载,但这是 LinqPad 的屏幕截图,显示了一些乱七八糟的字符(我添加了红色以进行保护)。看到黑色怪异的字符了吗?领先的"g"?怎么回事?
这是我用来获取解密文本的代码片段(我也尝试了不同的编码但无济于事):
using (Stream msDecrypt = new MemoryStream(cipherText, false))
using (Stream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (StreamReader srDecrypt = new StreamReader(csDecrypt, System.Text.Encoding.UTF8, false, 1024, true))
{
plaintext = srDecrypt.ReadToEnd();
}
如果我尝试使用 NewtonSoft BsonReader 使用 MassTransit 样式的解密,当它尝试调用 CryptoStream 对象上的 Dispose 时,我得到 "CryptographicException: Padding is invalid and cannot be removed":
using (Stream msDecrypt = new MemoryStream(cipherText, false))
using (Stream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (var jsonReader = new BsonReader(csDecrypt))
{
envelope = deserializer.Deserialize<MessageEnvelope>(jsonReader);
}
我做错了什么?
更新: 如果我粘贴到Notepad++,它会显示很多控制字符。该字符串以 gmessageId 开头(EOT 和 STX 是控制字符)。有很多 STX 字符 - 我认为这些应该是引号或冒号之类的...我如何将它们转换为正确的符号?
第二种方法是正确的;您想使用 BsonReader 反序列化为 MassTransit MessageEnvelope 实例。我得到 "CryptographicException: Padding is invalid and cannot be removed" 因为我没有传递任何 DeserializerSettings...在 MassTransit 源代码中,他们像下面这样初始化反序列化器:
JsonSerializerSettings DeserializerSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
ObjectCreationHandling = ObjectCreationHandling.Auto,
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
ContractResolver = new JsonContractResolver(),
Converters = new List<JsonConverter>(new JsonConverter[]
{
new ListJsonConverter(),
new InterfaceProxyConverter(GreenPipes.Internals.Extensions.TypeCache.ImplementationBuilder),
new IsoDateTimeConverter {DateTimeStyles = System.Globalization.DateTimeStyles.RoundtripKind},
})
};
var _deserializer = JsonSerializer.Create(DeserializerSettings);
之前,我只是在做:
var _deserializer = new JsonSerializer();
因此在正确初始化反序列化器后,对 MessageEnvelope 的反序列化工作正常,您可以将其序列化回 Json 字符串,格式如下:
MassTransit.Serialization.MessageEnvelope envelope;
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
using (Stream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (BsonReader jsonReader = new Newtonsoft.Json.Bson.BsonReader(csDecrypt))
{
envelope = _deserializer.Deserialize<MessageEnvelope>(jsonReader);
}
string output = JsonConvert.SerializeObject(envelope, Newtonsoft.Json.Formatting.Indented);
return output;
这假定 MassTransit 3.4、Newtonsoft.Json 9.0.1(又名 Json.NET)和 GreenPipes (1.0.6)。在上面的代码中,我在这些库中为 类 添加了完整的命名空间。
我正在使用 MassTransit 3.4 和 EncryptedSerializer。消息由我的应用程序正确加密和解密,但现在我希望能够解码出现在 RabbitMQ“_error”队列中的 base64 编码消息。我想编写一些程序来允许用户发现 base64 编码和加密消息的内容,但我正在努力正确解码消息。
这是我到目前为止所做的。 Copy/paste 将 RabbitMQ 管理中的 "Payload" 位 UI 放入我的文本编辑器并尝试 运行 编码为 Convert.FromBase64String(text),然后将字节数组传递给像one found here这样的解密函数。这几乎有效——我以纯文本形式看到了有效载荷的大部分字符,但许多字符都被弄乱了。我无法共享整个消息有效负载,但这是 LinqPad 的屏幕截图,显示了一些乱七八糟的字符(我添加了红色以进行保护)。看到黑色怪异的字符了吗?领先的"g"?怎么回事?
这是我用来获取解密文本的代码片段(我也尝试了不同的编码但无济于事):
using (Stream msDecrypt = new MemoryStream(cipherText, false))
using (Stream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (StreamReader srDecrypt = new StreamReader(csDecrypt, System.Text.Encoding.UTF8, false, 1024, true))
{
plaintext = srDecrypt.ReadToEnd();
}
如果我尝试使用 NewtonSoft BsonReader 使用 MassTransit 样式的解密,当它尝试调用 CryptoStream 对象上的 Dispose 时,我得到 "CryptographicException: Padding is invalid and cannot be removed":
using (Stream msDecrypt = new MemoryStream(cipherText, false))
using (Stream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (var jsonReader = new BsonReader(csDecrypt))
{
envelope = deserializer.Deserialize<MessageEnvelope>(jsonReader);
}
我做错了什么?
更新: 如果我粘贴到Notepad++,它会显示很多控制字符。该字符串以 gmessageId 开头(EOT 和 STX 是控制字符)。有很多 STX 字符 - 我认为这些应该是引号或冒号之类的...我如何将它们转换为正确的符号?
第二种方法是正确的;您想使用 BsonReader 反序列化为 MassTransit MessageEnvelope 实例。我得到 "CryptographicException: Padding is invalid and cannot be removed" 因为我没有传递任何 DeserializerSettings...在 MassTransit 源代码中,他们像下面这样初始化反序列化器:
JsonSerializerSettings DeserializerSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
ObjectCreationHandling = ObjectCreationHandling.Auto,
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
ContractResolver = new JsonContractResolver(),
Converters = new List<JsonConverter>(new JsonConverter[]
{
new ListJsonConverter(),
new InterfaceProxyConverter(GreenPipes.Internals.Extensions.TypeCache.ImplementationBuilder),
new IsoDateTimeConverter {DateTimeStyles = System.Globalization.DateTimeStyles.RoundtripKind},
})
};
var _deserializer = JsonSerializer.Create(DeserializerSettings);
之前,我只是在做:
var _deserializer = new JsonSerializer();
因此在正确初始化反序列化器后,对 MessageEnvelope 的反序列化工作正常,您可以将其序列化回 Json 字符串,格式如下:
MassTransit.Serialization.MessageEnvelope envelope;
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
using (Stream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (BsonReader jsonReader = new Newtonsoft.Json.Bson.BsonReader(csDecrypt))
{
envelope = _deserializer.Deserialize<MessageEnvelope>(jsonReader);
}
string output = JsonConvert.SerializeObject(envelope, Newtonsoft.Json.Formatting.Indented);
return output;
这假定 MassTransit 3.4、Newtonsoft.Json 9.0.1(又名 Json.NET)和 GreenPipes (1.0.6)。在上面的代码中,我在这些库中为 类 添加了完整的命名空间。