首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于XTEA的挑战响应认证

基于XTEA的挑战响应认证
EN

Stack Overflow用户
提问于 2018-03-26 20:48:55
回答 1查看 179关注 0票数 0

我有两个ESP8266微控制器板:

板A正在运行HTTP服务器,并且能够通过来自板B (即HTTP客户端)的GET请求来切换中继。

为了确保只有董事会B,而没有其他人,将切换在A上的放松,我想实现某种挑战响应认证。

我的想法如下:

  1. B局要求A局切换继电器
  2. 板A发送一些随机字节作为挑战
  3. 板B用XTEA算法加密这些原始字节,并将值返回给A板
  4. 董事会A破译来自董事会B的反应,并将其与自己的结果进行比较。如果响应到达太晚(例如,在1秒之后)或响应无效,则身份验证将被中止,下一次将生成一个新的挑战。如果响应是有效的,继电器将切换,并将有一个新的挑战,为下一次尝试。

因此,如果攻击者正在监听网络通信,他将同时接收原始字节和加密字节。

我要问你的问题:

  1. 如果攻击者知道原始字节和加密字节,是否(很容易)计算XTEA密钥?
  2. 所描述的方法对我的问题是一个合理的解决方案吗?

谢谢你,克里斯

EN

回答 1

Stack Overflow用户

发布于 2019-03-03 21:29:04

免责声明:我不是密码学专家。

如果攻击者知道原始字节和加密字节,是否(很容易)计算XTEA密钥?

不,你仍然需要做一个蛮力来推断关键和使用的子弹数,AFAIK。(至少如果您正在使用19轮或更多,因为目前唯一已知的XTEA密码攻击会影响到18轮或更少,截至2009年。但是,考虑到默认和推荐的是32轮,这应该不是一个问题,除非您使用自定义和低数量的回合..。就像18)

所描述的方法对我的问题是一个合理的解决方案吗?

您的协议容易受到来自MITM攻击者的比特翻转攻击,以及not提供的保护,防止窥探/监视,MITM攻击者将知道您发出的命令,并能够更改所给命令,这两种命令都可以很容易地避免.

我认为最好是客户端只请求随机字节作为令牌,并将实际的命令与加密的令牌一起发送。这将保护您的命令不被窥探,它将使MITM攻击者无法推断您发送的命令,即使攻击者知道协议的工作原理,因为令牌现在是加密命令的盐。但是,即使攻击者不知道密钥,您仍然容易受到MITM攻击者的比特翻转,因此您还应该添加一个校验和,以确保密文没有被篡改.对客户来说呢:

代码语言:javascript
复制
// start with the actual command
$data=encrypt("switch_relay(5);"); // or whatever
function encrypt(string $command){
// because of XTEA length padding, we need to tell the server the inner command length, so add a big endian 16 bit `size header`
$data=to_big_endian_uint16_t(strlen($data)).$data;
// get a unique 1-time-token? this should serve as salt AND protect against replay attack
$token=fetchToken();
// add the token
$data=$token.$data;
// now calculate a checksum to protect against bit-flipping attacks
$checksum=hash('adler32be',$data); // or whatever checksum you prefer. just has to be strong enough to detect random bit-flipping from attackers that can't decrypt-modify-encrypt because they don't know the encryption key, see https://en.wikipedia.org/wiki/Malleability_(cryptography) / https://en.wikipedia.org/wiki/Bit-flipping_attack

// add checksum
$data=$checksum.$data;
// encrypt data
$data=XTEA::encrypt($data, $key, XTEA::PAD_RANDOM, 32);
return $data;
}

在此之后,我通常会添加另一个大小头,以便服务器知道要为整个数据包读取多少字节,但是既然您说您使用的是HTTP协议,那么我假设您将使用一个Content-Length: X头作为外部大小的头。(或者如果您不这样做,那么您可能应该在x茶加密之后再执行一次$data=big_endian_uint16_t(strlen($data)).$data; )

对于服务器来说,请执行以下操作

代码语言:javascript
复制
function decrypt(string $data){
     // 4=checksum 8=token 2=inner_command_length
     if(strlen($data) < (4+8+2) || strlen($data) % 8 !== 0){
         // can't be an xtea-encrypted command, wrong length.
         return ERR_INVALID_LENGTH;
     }
    $data=XTEA::decrypt($data,$key,32);
    $checksum=substr($data,0,4);
    $data=substr($data,4);
    if(hash('adler32be',$data)!=$checksum){
        // checksum fail, can't be an xtea-encrypted command (or maybe it was corrupted or tampered with?)
       return ERR_INVALID_CHECKSUM;
    }
    $token=substr($data,0,8);
    $data=substr($data,8);
    if(!is_valid_token($token)){
        return ERR_INVALID_TOKEN;
    }
    $inner_size_len=big_endian_uint16_t_to_native_number(substr($data,0,2));
    $data=substr($data,2);
    if(strlen($data) < $inner_size_len){
        return ERR_INVALID_INNER_SIZE;
    }
    // remove padding bytes
    $data=substr($data,0,$inner_size_len);
    return $data; // the actual decrypted command
}

..?

(我仍然看到三个潜在的问题,1:向前保密是不提供的,因为你需要更复杂的东西,我认为。2:攻击者可能会拒绝--通过请求一次令牌来攻击您,直到您耗尽ram或其他任何东西,从而阻止合法客户端生成令牌,但由于令牌生存期为1秒,它必须是持续的主动攻击,并且一旦攻击者被阻止/删除,就停止工作。3:如果命令可以大于65535字节,您可能希望切换到32位大小的头,或者如果命令可以超过4GB,则可能希望切换到64位大小的标头,以此类推。但是如果您的命令很小,那么65535字节的16位大小的头就足够了吗?)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49500361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档