Go – 如何从字符串设置 RSA 公钥模数?

huangapple go评论116阅读模式
英文:

Go - How to Set RSA PublicKey Modulus from String?

问题

我正在尝试使用Go的RSA包对密码进行加密。

以下是我目前的代码:

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. "net/http"
  6. "strconv"
  7. "io/ioutil"
  8. "encoding/json"
  9. "errors"
  10. "crypto/rsa"
  11. "crypto/rand"
  12. //"math/big"
  13. )
  14. func main() {
  15. if err := Login("username", "password"); err != nil {
  16. fmt.Println(err)
  17. }
  18. }
  19. func Login(username, password string) error {
  20. doNotCache := strconv.FormatInt(time.Now().UnixNano() / int64(time.Millisecond), 10)
  21. // 获取RSA密钥
  22. resp, err := http.PostForm("https://steamcommunity.com/login/getrsakey/", map[string][]string{
  23. "donotcache": {doNotCache},
  24. "username": {username},
  25. })
  26. if err != nil {
  27. return err
  28. }
  29. content, err := ioutil.ReadAll(resp.Body)
  30. if err != nil {
  31. return err
  32. }
  33. var decoded map[string]interface{}
  34. err = json.Unmarshal(content, &decoded)
  35. if err != nil {
  36. return err
  37. }
  38. if decoded["success"] != true {
  39. return errors.New("无法获取RSA密钥。")
  40. }
  41. // 设置加密变量
  42. var privateKey *rsa.PrivateKey
  43. var publicKey *rsa.PublicKey
  44. var plain_text, encrypted []byte
  45. plain_text = []byte(password)
  46. // 生成私钥
  47. if privateKey, err = rsa.GenerateKey(rand.Reader, 1024); err != nil {
  48. return err
  49. }
  50. privateKey.Precompute()
  51. if err = privateKey.Validate(); err != nil {
  52. return err
  53. }
  54. publicKey.N = decoded["publickey_mod"].(string) // <- 这样不对,我需要从publickey_mod字符串创建一个大整数(big.Int)类型的模数
  55. publicKey.E = decoded["publickey_exp"].(int)
  56. encrypted, err = rsa.EncryptPKCS1v15(rand.Reader, publicKey, plain_text)
  57. if err != nil {
  58. return err
  59. }
  60. fmt.Printf("PKCS1加密 [%s] 为 \n[%x]\n", string(plain_text), encrypted)
  61. return nil
  62. }

我无法将publicKey.N的值设置为给定字符串的big.Int类型。

变量decoded["publickey_mod"]看起来像这样:

D3ABCD8303F887E0C7B390E088F24A797FE7084555FFB8BCE21F25EDD1F0DD02F48743EBAEC6BEEA6789DDC2AB51C7297A73957AC5CBEE7F4F8281EF6F47EDBDC83C366CDDAF087802082BE1620749754D05078F9EE4E71B4B6B5B3C6B999652F99F019B65468C632FC918C6840B63F801A49C5938F7BFCEB8EB913222A568CB2FE2F3E90911C1EAE9592F2811FD9E156068ABE18540542647D13A70D73F6DC5363A68426C3F9B1EC20FB29BB6920D784DF7724B31321A3CF9320CC657CA4044BB59AE4AFC4497FEC0DC032004183D5116F456A0C9A303E942EEEA6635A4E00C8DED8D6EAB67708682AC04FC18AB3CA1705C18E17DA9C6F06E2A0FDC905C88E3

而变量decoded["publickey_mod"]看起来像010001

我正在尝试为https://steamcommunity.com/加密这个密码。


我以前使用PHP使用名为Math_BigInteger的类使用相同的方法进行加密,以下是我创建publickey和加密密码的方式:

  1. $key = array(
  2. 'n' => new Math_BigInteger($curl->response->publickey_mod,16),
  3. 'e' => new Math_BigInteger($curl->response->publickey_exp,16)
  4. );
  5. // 定义指数
  6. define('CRYPT_RSA_EXPONENT', 010001);
  7. // 加载密钥
  8. $rsa->loadKey($key)
  9. // 设置参数
  10. $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
  11. $rsa->setHash('sha256');
  12. // 加密密码
  13. $encrypted_password = base64_encode($rsa->encrypt($password));

非常感谢您的帮助。

英文:

I am trying to encrypt a password with Go's RSA package.

Here is what I have so far:

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;time&quot;
  5. &quot;net/http&quot;
  6. &quot;strconv&quot;
  7. &quot;io/ioutil&quot;
  8. &quot;encoding/json&quot;
  9. &quot;errors&quot;
  10. &quot;crypto/rsa&quot;
  11. &quot;crypto/rand&quot;
  12. //&quot;math/big&quot;
  13. )
  14. func main() {
  15. if err := Login(&quot;username&quot;, &quot;password&quot;); err != nil {
  16. fmt.Println(err)
  17. }
  18. }
  19. func Login(username, password string) error {
  20. doNotCache := strconv.FormatInt(time.Now().UnixNano() / int64(time.Millisecond), 10)
  21. // Get RSA Key
  22. resp, err := http.PostForm(&quot;https://steamcommunity.com/login/getrsakey/&quot;, map[string][]string{
  23. &quot;donotcache&quot;: {doNotCache},
  24. &quot;username&quot;: {username},
  25. })
  26. if err != nil {
  27. return err
  28. }
  29. content, err := ioutil.ReadAll(resp.Body)
  30. if err != nil {
  31. return err
  32. }
  33. var decoded map[string]interface{}
  34. err = json.Unmarshal(content, &amp;decoded)
  35. if err != nil {
  36. return err
  37. }
  38. if decoded[&quot;success&quot;] != true {
  39. return errors.New(&quot;Failed to retrieve RSA key.&quot;)
  40. }
  41. // Set encryption variables
  42. var privateKey *rsa.PrivateKey
  43. var publicKey *rsa.PublicKey
  44. var plain_text, encrypted []byte
  45. plain_text = []byte(password)
  46. // Generate Private Key
  47. if privateKey, err = rsa.GenerateKey(rand.Reader, 1024); err != nil {
  48. return err
  49. }
  50. privateKey.Precompute()
  51. if err = privateKey.Validate(); err != nil {
  52. return err
  53. }
  54. publicKey.N = decoded[&quot;publickey_mod&quot;].(string) // &lt;- This is not right, I need to create a modulus from the publickey_mod string and it needs to be of type big.Int
  55. publicKey.E = decoded[&quot;publickey_exp&quot;].(int)
  56. encrypted, err = rsa.EncryptPKCS1v15(rand.Reader, publicKey, plain_text)
  57. if err != nil {
  58. return err
  59. }
  60. fmt.Printf(&quot;PKCS1 Encrypted [%s] to \n[%x]\n&quot;, string(plain_text), encrypted)
  61. return nil
  62. }

I am unable to set the publicKey.N value to a big.Int from a given string.

variable decoded[&quot;publickey_mod&quot;] looks something like this:

D3ABCD8303F887E0C7B390E088F24A797FE7084555FFB8BCE21F25EDD1F0DD02F48743EBAEC6BEEA6789DDC2AB51C7297A73957AC5CBEE7F4F8281EF6F47EDBDC83C366CDDAF087802082BE1620749754D05078F9EE4E71B4B6B5B3C6B999652F99F019B65468C632FC918C6840B63F801A49C5938F7BFCEB8EB913222A568CB2FE2F3E90911C1EAE9592F2811FD9E156068ABE18540542647D13A70D73F6DC5363A68426C3F9B1EC20FB29BB6920D784DF7724B31321A3CF9320CC657CA4044BB59AE4AFC4497FEC0DC032004183D5116F456A0C9A303E942EEEA6635A4E00C8DED8D6EAB67708682AC04FC18AB3CA1705C18E17DA9C6F06E2A0FDC905C88E3

and variable decoded[&quot;publickey_mod&quot;] looks something like 010001

I am trying to encrypt a this password for https://steamcommunity.com/.


I have encrypted with this exact method using PHP before with a class called Math_BigInteger and this is how I made the publickey and encrypted the password:

  1. $key = array(
  2. &#39;n&#39; =&gt; new Math_BigInteger($curl-&gt;response-&gt;publickey_mod,16),
  3. &#39;e&#39; =&gt; new Math_BigInteger($curl-&gt;response-&gt;publickey_exp,16)
  4. );
  5. // Define exponent
  6. define(&#39;CRYPT_RSA_EXPONENT&#39;, 010001);
  7. // Load the key
  8. $rsa-&gt;loadKey($key)
  9. // Set settings
  10. $rsa-&gt;setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
  11. $rsa-&gt;setHash(&#39;sha256&#39;);
  12. // Encrypt password
  13. $encrypted_password = base64_encode($rsa-&gt;encrypt($password));

Help would be extremely appreciated, thanks in advance.

https://play.golang.org/p/wmkgu2_Q20

答案1

得分: 1

decoded["publickey_mod"]是一个十六进制字符串,你需要将它转换为big.Int类型:

  1. publicKey.N, _ = new(big.Int).SetString(decoded["publickey_mod"].(string), 16 /* = base 16 */)
  2. // json numbers are float64 by default unless you use a struct and force a type
  3. publicKey.E = int(decoded["publickey_exp"].(float64))
英文:

decoded[&quot;publickey_mod&quot;] is a hex string, you need to convert it to a big.Int:

  1. publicKey.N, _ = new(big.Int).SetString(decoded[&quot;publickey_mod&quot;].(string), 16 /* = base 16 */)
  2. // json numbers are float64 by default unless you use a struct and force a type
  3. publicKey.E = int(decoded[&quot;publickey_exp&quot;].(float64))

huangapple
  • 本文由 发表于 2016年4月6日 20:10:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/36450743.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定