- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在计算完成消息的 MAC 时遇到问题。RFC 给出了公式
HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length + TLSCompressed.fragment));
但是tlsCompressed(在这种情况下是tlsplaintext,因为没有使用压缩)不包含版本信息:(十六进制转储)
14 00 00 0c 2c 93 e6 c5 d1 cb 44 12 bd a0 f9 2d
第一个字节是 tlsplaintext.type,然后是 uint24 长度。
完整的消息,附加了 MAC 和填充,在加密之前是
1400000c2c93e6c5d1cb4412bda0f92dbc175a02daab04c6096da8d4736e7c3d251381b10b
我尝试使用以下参数(符合 rfc)计算 hmac,但它不起作用:
uint64 seq_num
uint8 tlsplaintext.type
uint8 tlsplaintext.version_major
uint8 tlscompressed.version_minor
uint16 tlsplaintext.length
opaque tlsplaintext.fragment
我也试过省略版本并使用 uint24 长度代替。运气不好。
我的 hmac_hash()
函数不会是问题所在,因为到目前为止它一直有效。我还能够计算 verify_data 并验证它。因为这是新连接状态下发送的第一条消息,所以序号为0。
那么,最终报文的MAC计算参数到底是什么?
最佳答案
这是来自 Forge 的相关来源(TLS 1.0 的 JS 实现):
var hmac_sha1 = function(key, seqNum, record) {
/* MAC is computed like so:
HMAC_hash(
key, seqNum +
TLSCompressed.type +
TLSCompressed.version +
TLSCompressed.length +
TLSCompressed.fragment)
*/
var hmac = forge.hmac.create();
hmac.start('SHA1', key);
var b = forge.util.createBuffer();
b.putInt32(seqNum[0]);
b.putInt32(seqNum[1]);
b.putByte(record.type);
b.putByte(record.version.major);
b.putByte(record.version.minor);
b.putInt16(record.length);
b.putBytes(record.fragment.bytes());
hmac.update(b.getBytes());
return hmac.digest().getBytes();
};
The function that creates the Finished record :
tls.createFinished = function(c) {
// generate verify_data
var b = forge.util.createBuffer();
b.putBuffer(c.session.md5.digest());
b.putBuffer(c.session.sha1.digest());
// TODO: determine prf function and verify length for TLS 1.2
var client = (c.entity === tls.ConnectionEnd.client);
var sp = c.session.sp;
var vdl = 12;
var prf = prf_TLS1;
var label = client ? 'client finished' : 'server finished';
b = prf(sp.master_secret, label, b.getBytes(), vdl);
// build record fragment
var rval = forge.util.createBuffer();
rval.putByte(tls.HandshakeType.finished);
rval.putInt24(b.length());
rval.putBuffer(b);
return rval;
};
处理 Finished 消息的代码有点长,可以是 found here .我看到我在该代码中有一条评论,听起来它可能与您的问题相关:
// rewind to get full bytes for message so it can be manually
// digested below (special case for Finished messages because they
// must be digested *after* handling as opposed to all others)
这是否有助于您发现实现中的任何内容?
更新 1
根据您的评论,我想澄清一下 TLSPlainText 的工作原理。 TLSPlainText 是 TLS 协议(protocol)的主要“记录”。它是特定内容类型消息的“包装器”或“信封”。它总是看起来像这样:
struct {
ContentType type;
ProtocolVersion version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;
所以它总是有一个版本。 Finished 消息是一种握手消息。所有握手消息的内容类型都是 22。握手消息如下所示:
struct {
HandshakeType msg_type;
uint24 length;
body
} Handshake;
握手消息是其他消息的另一个信封/包装器,例如 Finished 消息。在这种情况下,正文将是一条 Finished 消息 (HandshakeType 20),如下所示:
struct {
opaque verify_data[12];
} Finished;
要实际发送 Finished 消息,您必须将其包装在 Handshake 消息信封中,然后像任何其他消息一样,您必须将其包装在 TLS 记录 (TLSPlainText) 中。最终结果看起来/代表这样的东西:
struct {
ContentType type=22;
ProtocolVersion version=<major, minor>;
uint16 length=<length of fragment>;
opaque fragment=<struct {
HandshakeType msg_type=20;
uint24 length=<length of finished message>;
body=<struct {
opaque verify_data[12]>;
} Finished>
} Handshake>
} TLSPlainText;
然后,在运输之前,记录可能会被更改。您可以将这些更改视为获取记录并转换其片段(和片段长度)的操作。第一个操作压缩片段。压缩后,您计算 MAC,如上所述,然后将其附加到片段。然后加密片段(如果使用分组密码,则添加适当的填充)并将其替换为加密结果。因此,完成后,您仍然会得到一条包含类型、版本、长度和片段的记录,但片段已加密。
所以,我们很清楚,当您计算 Finished 消息的 MAC 时,想象一下将上面的 TLSPlainText(假设没有如您指示的那样进行压缩)传递给一个函数。此函数采用此 TLSPlainText 记录,该记录具有类型、版本、长度和片段的属性。上面的HMAC函数运行在记录上。 HMAC key 和序列号(此处为 0)通过 session 状态提供。因此,您可以看到 HMAC 功能所需的一切都可用。
无论如何,希望这能更好地解释协议(protocol)的工作原理,并且可能会揭示您的实现出了什么问题。
关于ssl - TLS 1.0-计算完成的消息MAC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23596622/
更新到 Xcode 12.2 后,由于与 Apple Silicon 相关的链接错误,我的项目开始无法编译。我似乎已经修复了大部分问题,但是一个构建静态链接框架的子项目给我带来了问题。然而,具有明显相
我有一台旧的 MacBook Pro,我在其中制作了两个应用程序并提交到应用程序商店。所以基本上签名身份在该机器的钥匙串(keychain)中。在 Mavericks 升级后,我不得不从那台计算机转移
我正在 MAC OSX 10.6 上编写一个示例应用程序,其 gcc 版本为 4.2。我正在使用 gcc 4.2 版编译应用程序。它在同一台机器上工作正常,但在 MAC OSX 10.5 (gcc 4
这是我的简单 mac 地址生成器: private String randomMACAddress(){ Random rand = new Random(); byte[] macA
我一直在寻找一种将十进制 MAC 地址转换为十六进制地址的方法。 例如 170.187.204.0.17.34至AA:BB:CC:00:11:22 . 致Convert HEX to Decimal
我想使用 UISceneSession 的委托(delegate)方法当用户将注意力从应用程序(窗口)移开,然后又回到应用程序(窗口)时,生命周期有助于通知我的 Mac Catalyst 应用程序。
我在签署 Mac 应用程序安装程序时遇到问题,我计划在 Mac 应用商店之外分发该应用程序。我正在使用开发人员安装程序证书来签署应用程序,但它给出了一些错误。下面是我用来签署应用程序的命令。 prod
Mac Catalyst 允许调整窗口大小,有没有办法为 Mac Catalyst 应用程序提供最小窗口大小? 最佳答案 只需将以下代码块添加到您的 application:didFinishLaun
这是一个非常理论性的问题,但对我来说很安静,即我如何进行下一步。 我正在开发一个SwiftUI MacOS应用程序,用户可以在其中上传自己的文件。元数据将存储在CoreData中,而我将文件手动存储在
滑动删除在 maccatalyst 中不起作用。相同的代码在 iPad 上运行良好。 在 maccatalyst 中未调用 UITableview trailingSwipeActionsConfig
我有两台 Mac,在进行 iPad 开发时,如果可以让另一台 Mac 启动模拟器并在构建完成后加载应用程序,我很感兴趣。 如果 iPad 应用程序在一台 Mac 屏幕和 Xcode 的模拟器中运行,所
我有一个用 objective-c 开发的 mac 应用程序。cpp 中还有另一个命令行中间应用程序,它是 native 主机应用程序,用于接收来自 chrome 扩展的消息。每当中间应用程序从扩展程
是否可以使用来自 Comodo 或 Thawte 的代码签名证书来签署应用程序并通过 Gatekeeper,或者我需要为此目的拥有 Mac 开发者订阅? 最佳答案 您必须是 Mac Developer
我正在使用 C++ 和 OpenGL/SDL 编写一个游戏,使用 Visual Studio 作为我的 IDE。我没有 Mac,甚至对这个平台都不熟悉。但我还是想发布给 Mac 用户。 我有三个问题。
我想将 MAC 地址 00163e2fbab7(存储为字符串)转换为其字符串表示形式 00:16:3e:2f:ba:b7。最简单的方法是什么? 最佳答案 使用一种完全迂回的方法来利用现有的一次将两个十
无法连接到Mac上的MySQL工作台。我收到以下错误:无法连接,服务器可能未运行。无法连接到‘127.0.0.1’上的MySQL服务器(61)如有帮助,将不胜感激。。谢谢!
我已经搜索了很长时间,似乎无法找到这个问题的答案。在 SO 上只找到两个问题/答案,但他们仍然没有回答这个问题 ( https://stackoverflow.com/search?q=netcore
我们在 Docker for Mac 中有一个 LoadBalancer 真是太酷了。 我对创建的端口有疑问: apiVersion: v1 kind: Service metadata: nam
我有一个我一直在从事的小型开源 OSX 项目,我想在 App Store 之外分发。 随着即将发布的 Mountain Lion,我想提供一个证书,以减少安装过程中的痛苦。 使用 App Store,
我的一台 Mac 没有互联网连接。我需要使用 docker pull。我的想法是,我将在我的一台具有互联网连接的 Mac 中使用 docker pull,然后将其复制到我没有互联网连接的 Mac。如何
我是一名优秀的程序员,十分优秀!