config.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package shadowsocks
  2. import (
  3. "crypto/cipher"
  4. "crypto/md5"
  5. "errors"
  6. "v2ray.com/core/common/crypto"
  7. "v2ray.com/core/common/protocol"
  8. )
  9. func (this *Account) GetCipher() (Cipher, error) {
  10. switch this.CipherType {
  11. case CipherType_AES_128_CFB:
  12. return &AesCfb{KeyBytes: 16}, nil
  13. case CipherType_AES_256_CFB:
  14. return &AesCfb{KeyBytes: 32}, nil
  15. case CipherType_CHACHA20:
  16. return &ChaCha20{IVBytes: 8}, nil
  17. case CipherType_CHACHA20_IEFT:
  18. return &ChaCha20{IVBytes: 12}, nil
  19. default:
  20. return nil, errors.New("Unsupported cipher.")
  21. }
  22. }
  23. func (this *Account) Equals(another protocol.Account) bool {
  24. if account, ok := another.(*Account); ok {
  25. return account.Password == this.Password
  26. }
  27. return false
  28. }
  29. func (this *Account) AsAccount() (protocol.Account, error) {
  30. return this, nil
  31. }
  32. func (this *Account) GetCipherKey() []byte {
  33. ct, err := this.GetCipher()
  34. if err != nil {
  35. return nil
  36. }
  37. return PasswordToCipherKey(this.Password, ct.KeySize())
  38. }
  39. type Cipher interface {
  40. KeySize() int
  41. IVSize() int
  42. NewEncodingStream(key []byte, iv []byte) (cipher.Stream, error)
  43. NewDecodingStream(key []byte, iv []byte) (cipher.Stream, error)
  44. }
  45. type AesCfb struct {
  46. KeyBytes int
  47. }
  48. func (this *AesCfb) KeySize() int {
  49. return this.KeyBytes
  50. }
  51. func (this *AesCfb) IVSize() int {
  52. return 16
  53. }
  54. func (this *AesCfb) NewEncodingStream(key []byte, iv []byte) (cipher.Stream, error) {
  55. stream := crypto.NewAesEncryptionStream(key, iv)
  56. return stream, nil
  57. }
  58. func (this *AesCfb) NewDecodingStream(key []byte, iv []byte) (cipher.Stream, error) {
  59. stream := crypto.NewAesDecryptionStream(key, iv)
  60. return stream, nil
  61. }
  62. type ChaCha20 struct {
  63. IVBytes int
  64. }
  65. func (this *ChaCha20) KeySize() int {
  66. return 32
  67. }
  68. func (this *ChaCha20) IVSize() int {
  69. return this.IVBytes
  70. }
  71. func (this *ChaCha20) NewEncodingStream(key []byte, iv []byte) (cipher.Stream, error) {
  72. return crypto.NewChaCha20Stream(key, iv), nil
  73. }
  74. func (this *ChaCha20) NewDecodingStream(key []byte, iv []byte) (cipher.Stream, error) {
  75. return crypto.NewChaCha20Stream(key, iv), nil
  76. }
  77. func PasswordToCipherKey(password string, keySize int) []byte {
  78. pwdBytes := []byte(password)
  79. key := make([]byte, 0, keySize)
  80. md5Sum := md5.Sum(pwdBytes)
  81. key = append(key, md5Sum[:]...)
  82. for len(key) < keySize {
  83. md5Hash := md5.New()
  84. md5Hash.Write(md5Sum[:])
  85. md5Hash.Write(pwdBytes)
  86. md5Hash.Sum(md5Sum[:0])
  87. key = append(key, md5Sum[:]...)
  88. }
  89. return key
  90. }