crypto.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package seclib2
  15. import (
  16. "crypto"
  17. "crypto/dsa"
  18. "crypto/ecdsa"
  19. "crypto/rand"
  20. "crypto/rsa"
  21. "crypto/sha1"
  22. "encoding/base64"
  23. "fmt"
  24. "golang.org/x/crypto/ssh"
  25. "yunion.io/x/log"
  26. )
  27. func exportSshPublicKey(pubkey interface{}) ([]byte, error) {
  28. pub, err := ssh.NewPublicKey(pubkey)
  29. if err != nil {
  30. return nil, err
  31. }
  32. return ssh.MarshalAuthorizedKey(pub), nil
  33. }
  34. func ssh2CryptoPublicKey(key ssh.PublicKey) crypto.PublicKey {
  35. cryptoPub := key.(ssh.CryptoPublicKey)
  36. return cryptoPub.CryptoPublicKey()
  37. }
  38. func ssh2rsaPublicKey(key ssh.PublicKey) *rsa.PublicKey {
  39. cryptoKey := ssh2CryptoPublicKey(key)
  40. return cryptoKey.(*rsa.PublicKey)
  41. }
  42. func ssh2dsaPublicKey(key ssh.PublicKey) *dsa.PublicKey {
  43. cryptoKey := ssh2CryptoPublicKey(key)
  44. return cryptoKey.(*dsa.PublicKey)
  45. }
  46. func ssh2ecdsaPublicKey(key ssh.PublicKey) *ecdsa.PublicKey {
  47. cryptoKey := ssh2CryptoPublicKey(key)
  48. return cryptoKey.(*ecdsa.PublicKey)
  49. }
  50. func Encrypt(publicKey, origData []byte) ([]byte, error) {
  51. pub, _, _, _, err := ssh.ParseAuthorizedKey(publicKey)
  52. if err != nil {
  53. log.Errorf("parse authorized key error %s", err)
  54. return nil, err
  55. }
  56. if pub.Type() == ssh.KeyAlgoRSA {
  57. return rsa.EncryptOAEP(sha1.New(), rand.Reader, ssh2rsaPublicKey(pub), origData, nil)
  58. } else {
  59. var pubInf interface{}
  60. switch pub.Type() {
  61. case ssh.KeyAlgoDSA:
  62. pubInf = ssh2dsaPublicKey(pub)
  63. case ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521:
  64. pubInf = ssh2ecdsaPublicKey(pub)
  65. default:
  66. return nil, fmt.Errorf("unsupported key type %s", pub.Type())
  67. }
  68. pubStr, err := exportSshPublicKey(pubInf)
  69. if err != nil {
  70. return nil, err
  71. }
  72. return encryptAES(pubStr, origData)
  73. }
  74. }
  75. func Decrypt(privateKey, secret []byte) ([]byte, error) {
  76. priv, err := ssh.ParseRawPrivateKey(privateKey)
  77. if err != nil {
  78. return nil, err
  79. }
  80. switch priv.(type) {
  81. case *rsa.PrivateKey:
  82. rsaPriv := priv.(*rsa.PrivateKey)
  83. return rsa.DecryptOAEP(sha1.New(), rand.Reader, rsaPriv, secret, nil)
  84. case *dsa.PrivateKey:
  85. dsaPriv := priv.(*dsa.PrivateKey)
  86. dsaPub, err := exportSshPublicKey(&dsaPriv.PublicKey)
  87. if err != nil {
  88. return nil, err
  89. }
  90. return decryptAES(dsaPub, secret)
  91. case *ecdsa.PrivateKey:
  92. ecdsaPriv := priv.(*ecdsa.PrivateKey)
  93. ecdsaPub, err := exportSshPublicKey(&ecdsaPriv.PublicKey)
  94. if err != nil {
  95. return nil, err
  96. }
  97. return decryptAES(ecdsaPub, secret)
  98. }
  99. return nil, fmt.Errorf("unsupported")
  100. }
  101. func EncryptBase64(publicKey string, message string) (string, error) {
  102. secretBytes, err := Encrypt([]byte(publicKey), []byte(message))
  103. if err != nil {
  104. return "", err
  105. }
  106. return base64.StdEncoding.EncodeToString(secretBytes), nil
  107. }
  108. func DecryptBase64(privateKey string, secret string) (string, error) {
  109. secretBytes, err := base64.StdEncoding.DecodeString(secret)
  110. if err != nil {
  111. return "", err
  112. }
  113. msgBytes, err := Decrypt([]byte(privateKey), secretBytes)
  114. if err != nil {
  115. return "", err
  116. }
  117. return string(msgBytes), nil
  118. }