Molet

cookie防篡改

Molet 安全防护 2022-12-31 319浏览 0

概述:

除了session外,一般不会在客户端的cookies里保存过于重要的凭据,但电商应用有时候不可避免地存储了一些敏感数据到客户端,当然不希望被篡改。

目的:

让服务器端能识别cookie值被篡改了。

手法:

set-cookie时加上防篡改验证码。

如:

user_name=alex|bj95ef23cc6daecc475de

防篡改验证码的生成规则可以很简单:md5(cookieValue+key)或sha1(cookieValue+key),key可以是服务器端掌握的一个固定字符串,也可以很复杂(如后面的LTPA示例)。

核对规则是:

服务器端得到客户端送上来的cookie后,重新计算一下验证码,如一致,则未篡改。

示例2:IBM LTPA 的cookie签名

Lightweight Third-Party Authentication (LTPA)是IBM Websphere和Domino产品中使用的单点登录技术。

当服务器配置好LTPA认证方式,用户通过浏览器成功登录后,服务器会自动发送一个session cookie给浏览器;此Cookie中包含一个LTPA Token。

一个有效的LTPA Cookie能够在同一个认证域中被所有服务器自动认证。此Cookie中包含认证信息和时间戳。这些信息通过共享的3DES Key进行了bis 加密。使用公共密钥/私有密钥进行签名。

1)大致介绍:

LTPA Cookie原始值通过3DES密钥,使用DESede/ECB/PKCS5P进行加密。

此3DES密钥也是采用DESede/ECB/PKCS5P进行加密,加密后再使用事先提供的密钥密码 进行SHA-1 Hash,生成24个字节的密钥,再进行Base64编码。

如Dmonio里,LTPA Cookie值为以下公式组成:

SHA-1=LTPA版本号+创建时间+过期时间+用户名+Domino LTPA 密钥

LTPA Cookie= Base64(LTPA版本号+创建时间+过期时间+用户名+SHA-1)

如要解析LTPA Token,先得使用密钥密码 ,生成3DES密钥;再使用3DES密钥 解密 Token Cookie。也可以使用公共/私有密钥来签名或验证LTPA Cookie。

2)WebSphere LTPA 生成原理

首先,这个 cookie 由以下部分组成,以%进行分隔:

用户信息 ,格式为u:user\:<RealmName>/<UserDN>,如:u:user\:VGOLiveRealm/CN=squallzhong,O=VGOLive Technology

过期时间

签名信息, 如:

u:user\:VGOLiveRealm/CN=squallzhong,O=VGOLive Technology%1301558320666%Cy2CAeru5kEElGj0hrvYsKW2ZVsvvcu6Un573aeX55OO4G3EMYWc0e/ZbqDp1z7MS+ dLzniuUH4sYWCMpnKdm7ZGabwmV+WcraBl+y+yzwcl722gHVMOnDZAW7U3jEay9 Tk2yG4yXkMWU+617xndpVxke2jtS5wIyVVM3q7UDPw=

3)WebSphere LTPA Cookie 的解析

以下代码为解析从 WebSphere 或 Domino 发送过来的 LTPAToken Cookie。以Java为例:

01…

02 // LTPA 3DES 密钥

03 String ltpa3DESKey = "7dH4i81YepbVe+gF9XVUzE4C1Ca5g6A4Q69OFobJV9g=";

04 // LTPA 密钥密码

05 String ltpaPassword = "Passw0rd";

06 try {

07 // ***步,获得加密key

08 byte[] secretKey = getSecretKey(ltpa3DESKey, ltpaPassword);

09 // 第二步,使用加密key解密ltpa Cookie

10 String ltpaPlaintext = new String(decryptLtpaToken(tokenCipher,

11 secretKey));

12 displayTokenData(ltpaPlaintext);

13 } catch (Exception e) {

14 System.out.println("Caught inner: " + e);

15 }

16…

17 //获得安全Key

18 private static byte[] getSecretKey(String ltpa3DESKey, String password)

19 throws Exception {

20 // 使用SHA获得key密码的hash值

21 MessageDigest md = MessageDigest.getInstance("SHA");

22 md.update(password.getBytes());

23 byte[] hash3DES = new byte[24];

24 System.arraycopy(md.digest(), 0, hash3DES, 0, 20);

25 // 使用0替换后4个字节

26 Arrays.fill(hash3DES, 20, 24, (byte) 0);

27 // BASE64解码 ltpa3DESKey

28 byte[] decode3DES = Base64.decodeBase64(ltpa3DESKey.getBytes());

29 // 使用key密码hash值解密已Base64解码的ltpa3DESKey

30 return decrypt(decode3DES, hash3DES);

31 }

32 //解密LtpaToken

33 public static byte[] decryptLtpaToken(String encryptedLtpaToken, byte[] key)

34 throws Exception {

35 // Base64解码LTPAToken

36 final byte[] ltpaByteArray = Base64.decodeBase64(encryptedLtpaToken

37 .getBytes());

38 // 使用key解密已Base64解码的LTPAToken

39 return decrypt(ltpaByteArray, key);

40 }

41 // DESede/ECB/PKC5Padding解方法

42 public static byte[] decrypt(byte[] ciphertext, byte[] key)

43 throws Exception {

44 final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");

45 final KeySpec keySpec = new DESedeKeySpec(key);

46 final Key secretKey = SecretKeyFactory.getInstance("TripleDES")

47 .generateSecret(keySpec);

48 cipher.init(Cipher.DECRYPT_MODE, secretKey);

49 return cipher.doFinal(ciphertext);

50 }

51…

解析出来的LTPAToken信息以%分隔。

参考资源:

1)hannover,LTPA Cookie原理

转载请注明:IT运维空间 » 安全防护 » cookie防篡改

继续浏览有关 安全 的文章
发表评论