• PHP RSA研究


    最近研究了一下QQ邮箱的登录过程,发现QQ邮箱登录比较严谨,加了一些小技巧,其中一点就是用JavaScript对用户的密码做了一下RSA的加密,在它的登录页面里有一段

    1
    2
    3
    4
    5
    6
    7
    8
    
    var PublicKey = "CF87D7B4C864F4842F1D337491A48FFF54B73A17300E8E42FA365420393AC0346AE55D8AFAD975DFA175FAF0106CBA81AF1DDE4ACEC284DAC6ED9A0D8FEB1CC070733C58213EFFED46529C54CEA06D774E3CC7E073346AEBD6C66FC973F299EB74738E400B22B1E7CDC54E71AED059D228DFEB5B29C530FF341502AE56DDCFE9";
    var RSA = new RSAKey();
    RSA.setPublic(PublicKey, "10001");
    var Res = RSA.encrypt(document.form1.pp.value + '\n' + document.form1.ts.value + '\n');
    if (Res)
    {
    document.form1.p.value = hex2b64(Res);
    }

    再看看RSAKey的相关源码,应该是在http://m367.mail.qq.com/zh_CN/htmledition/js/safeauth.js里,看了一下还是蛮复杂的,我就在Google上搜一下有没有相关的资料,找到了这个网站《BigIntegers and RSA in JavaScript》, 看了一下他们的代码,和QQ里的基本一样嘛,估计QQ也是用了人家的代码,这篇文章里有密钥对的生成、加密解密的测试页面,由此推断QQ代码里的 PublicKey,应该是密钥对的modulus(也可以理解为公钥吧),并且QQ用的是1024位的密钥,那我们是否可以用这个modulus,使用 别的语言(比如PHP)来做密码加密呢?

    想到就做,我在Google上搜索一下“PHP RSA”,找到了这个网站http://www.edsko.net/misc/, 里面有PHP RSA的实现,不过我对它的rsa_encrypt($message, $public_key, $modulus, $keylength)方法产生了疑惑,它有4个参数,第一个是要加密的字串,那后面三个怎么填,我们现在仅知道的就是modulus了, 而$public_key和$keylength从何而来呢,真有点摸不着头脑了,还是看看它带的例子吧,原来它例子里是从密钥对文件中取得相关的信 息,QQ的密钥对文件自然取不到,那我只能自己生成一个密钥对文件,来看看有什么规律吧,在Linux下用openssl做

    openssl genrsa -out key.pem 1024

    生成了一个1024位的密钥对文件,可以打开看看,里面应该是Base64编码的,之后我们通过下面的命令可以得到modulus

    1
    2
    
    openssl rsa -in key.pem -noout -modulus
    Modulus=D192471B8699640F931FE6F4FACC3E990B894F894CEA5BEE0DCBD7A4B76752F7345CF9B5F1271001B724F7A0ABF0A6E911E309536F4BE4749E92DCC531B8E36B95969D206649C9DD2371B413A8DFD9B92569660B1499A5CD310B86A8FDE24988E456897A416D2E7B0B649F0714F322C57EF92563B21A448D1072FF3806C34C75

    比照QQ的,位数是一样的,接下来我们用命令

    openssl rsa -in key.pem -text -noout

    输出的内容如下:
    Private-Key: (1024 bit)
    modulus:
    00:d1:92:47:1b:86:99:64:0f:93:1f:e6:f4:fa:cc:
    3e:99:0b:89:4f:89:4c:ea:5b:ee:0d:cb:d7:a4:b7:
    67:52:f7:34:5c:f9:b5:f1:27:10:01:b7:24:f7:a0:
    ab:f0:a6:e9:11:e3:09:53:6f:4b:e4:74:9e:92:dc:
    c5:31:b8:e3:6b:95:96:9d:20:66:49:c9:dd:23:71:
    b4:13:a8:df:d9:b9:25:69:66:0b:14:99:a5:cd:31:
    0b:86:a8:fd:e2:49:88:e4:56:89:7a:41:6d:2e:7b:
    0b:64:9f:07:14:f3:22:c5:7e:f9:25:63:b2:1a:44:
    8d:10:72:ff:38:06:c3:4c:75
    publicExponent: 65537 (0×10001)
    privateExponent:
    00:83:d3:d9:08:f6:95:3c:bd:13:56:29:09:07:4e:
    3d:3e:36:64:8c:74:98:be:7f:4f:72:bc:3c:0c:f0:
    15:7d:b9:e4:e5:6b:6a:c8:a4:42:cc:61:71:4e:97:
    72:30:f2:3d:80:33:e9:a4:e3:48:c1:0f:9e:c4:51:
    3d:75:f6:90:8e:f3:c3:f8:ce:45:59:2a:67:42:a8:
    c6:d0:4c:1d:12:c4:cf:53:f8:b1:58:b4:e1:23:71:
    0e:e9:e9:e0:40:3d:9a:99:e3:5f:e1:93:04:e2:0a:
    60:34:77:56:be:f9:8f:e6:4e:87:23:46:48:ba:38:
    9d:dd:46:ce:20:b7:82:27:cd
    prime1:
    00:ee:a9:e4:70:9c:d4:fe:bf:cd:87:5c:00:cb:ea:
    ef:82:92:e1:88:f7:99:6a:42:09:f4:fd:78:93:bd:
    30:28:1f:2e:ed:c1:cd:d3:60:8b:34:52:89:a7:ac:
    98:37:cd:96:81:1e:57:2f:46:08:0e:8d:fb:13:92:
    8d:f5:7a:50:5f
    prime2:
    00:e0:cb:65:5e:31:f2:3b:c0:7f:93:ae:d9:6c:35:
    75:e5:ce:8b:37:7d:39:ce:82:dd:9b:43:00:09:a6:
    d8:c1:ab:bc:10:fe:3d:56:34:fe:bd:38:fe:fc:6c:
    f2:74:a8:d6:40:25:e5:5a:35:7b:d0:24:71:44:8d:
    53:23:71:83:ab
    exponent1:
    4b:d5:7f:d8:a8:7c:a5:55:9c:a0:de:03:02:c8:6b:
    c2:39:99:a0:43:cc:63:8f:08:4a:e8:1f:60:12:45:
    32:fa:75:96:e6:75:d8:2c:5d:0f:0b:0a:e2:54:5d:
    29:9e:11:ac:85:4f:7e:9d:ea:01:75:eb:c9:94:4f:
    b7:28:5e:51
    exponent2:
    00:9b:9f:d4:56:a8:e7:55:3c:88:55:fa:97:a5:55:
    41:80:ce:44:0d:2f:51:a4:c9:6e:97:fd:83:7a:2b:
    1b:26:c1:38:da:de:d8:21:e5:60:72:29:92:45:b9:
    3b:05:4e:99:bd:21:3f:2d:fb:96:f2:db:37:db:48:
    a7:c5:02:e2:2f
    coefficient:
    00:c2:75:38:a5:02:24:39:1e:0e:e9:ec:56:6a:31:
    5d:38:82:ca:3e:9b:67:cb:40:7e:7b:2f:91:26:bb:
    4e:64:3d:60:53:f1:21:67:8b:b7:af:f8:2e:95:f7:
    af:cf:42:75:ab:6c:5c:42:97:42:17:94:17:ff:e0:
    b9:cb:c9:e8:6d

    通过它例子的代码,我明白了,$public_key应该是1024,$keylength就是65537,$modulus不能直接用这段文字,要先转成BigInteger,再转成文本传进去,BigInteger实现在PEAR里有,http://pear.php.net/package/Math_BigInteger

    我们接下来就写程序吧

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    include('rsa.php');
    include('BigInteger.php');
     
    $public = 65537;
    $modulus = "D192471B8699640F931FE6F4FACC3E990B894F894CEA5BEE0DCBD7A4B76752F7345CF9B5F1271001B724F7A0ABF0A6E911E309536F4BE4749E92DCC531B8E36B95969D206649C9DD2371B413A8DFD9B92569660B1499A5CD310B86A8FDE24988E456897A416D2E7B0B649F0714F322C57EF92563B21A448D1072FF3806C34C75";
    $keylength = 1024;
    $modulus_16 = new Math_BigInteger($modulus,16);
    $mend = $modulus_16->toString();
     
    $encrypted = rsa_encrypt("test", $public, $mend, $keylength);
    echo bin2hex($encrypted); //这里也可以用Base64,QQ就是Base64

    最后说一下我对于RSA的理解,首先生成了公钥/私钥的密钥对,之后把公钥发布出去,外部系统用公钥加密,传给内部系统用私钥解密。

  • 相关阅读:
    《软件架构设计》温昱著读后感(一)
    质量属性II(信息领域热词分析)
    质量属性
    2020寒假学习进度报告16
    2020寒假学习进度报告15
    Nginx运行报错unknown directive ""
    使用ajax的几种方式
    Shiro中@RequiresAuthentication等等注解介绍
    shiro自定义异常无法被捕获总是抛出AuthenticationException解决方案
    java中String和int相互转换常用方法详解
  • 原文地址:https://www.cnblogs.com/breg/p/2321849.html
Copyright © 2020-2023  润新知