crypto_type.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package osscrypto
  2. import (
  3. "crypto/rand"
  4. "encoding/binary"
  5. "fmt"
  6. "io"
  7. math_rand "math/rand"
  8. "time"
  9. )
  10. // MasterCipher encrypt or decrpt CipherData
  11. // support master key: rsa && ali kms
  12. type MasterCipher interface {
  13. Encrypt([]byte) ([]byte, error)
  14. Decrypt([]byte) ([]byte, error)
  15. GetWrapAlgorithm() string
  16. GetMatDesc() string
  17. }
  18. // ContentCipherBuilder is used to create ContentCipher for encryting object's data
  19. type ContentCipherBuilder interface {
  20. ContentCipher() (ContentCipher, error)
  21. ContentCipherEnv(Envelope) (ContentCipher, error)
  22. GetMatDesc() string
  23. }
  24. // ContentCipher is used to encrypt or decrypt object's data
  25. type ContentCipher interface {
  26. EncryptContent(io.Reader) (io.ReadCloser, error)
  27. DecryptContent(io.Reader) (io.ReadCloser, error)
  28. Clone(cd CipherData) (ContentCipher, error)
  29. GetEncryptedLen(int64) int64
  30. GetCipherData() *CipherData
  31. GetAlignLen() int
  32. }
  33. // Envelope is stored in oss object's meta
  34. type Envelope struct {
  35. IV string
  36. CipherKey string
  37. MatDesc string
  38. WrapAlg string
  39. CEKAlg string
  40. UnencryptedMD5 string
  41. UnencryptedContentLen string
  42. }
  43. func (el Envelope) IsValid() bool {
  44. return len(el.IV) > 0 &&
  45. len(el.CipherKey) > 0 &&
  46. len(el.WrapAlg) > 0 &&
  47. len(el.CEKAlg) > 0
  48. }
  49. func (el Envelope) String() string {
  50. return fmt.Sprintf("IV=%s&CipherKey=%s&WrapAlg=%s&CEKAlg=%s", el.IV, el.CipherKey, el.WrapAlg, el.CEKAlg)
  51. }
  52. // CipherData is secret key information
  53. type CipherData struct {
  54. IV []byte
  55. Key []byte
  56. MatDesc string
  57. WrapAlgorithm string
  58. CEKAlgorithm string
  59. EncryptedIV []byte
  60. EncryptedKey []byte
  61. }
  62. func (cd *CipherData) RandomKeyIv(keyLen int, ivLen int) error {
  63. math_rand.Seed(time.Now().UnixNano())
  64. // Key
  65. cd.Key = make([]byte, keyLen)
  66. if _, err := io.ReadFull(rand.Reader, cd.Key); err != nil {
  67. return err
  68. }
  69. // sizeof uint64
  70. if ivLen < 8 {
  71. return fmt.Errorf("ivLen:%d less than 8", ivLen)
  72. }
  73. // IV:reserve 8 bytes
  74. cd.IV = make([]byte, ivLen)
  75. if _, err := io.ReadFull(rand.Reader, cd.IV[0:ivLen-8]); err != nil {
  76. return err
  77. }
  78. // only use 4 byte,in order not to overflow when SeekIV()
  79. randNumber := math_rand.Uint32()
  80. cd.SetIV(uint64(randNumber))
  81. return nil
  82. }
  83. func (cd *CipherData) SetIV(iv uint64) {
  84. ivLen := len(cd.IV)
  85. binary.BigEndian.PutUint64(cd.IV[ivLen-8:], iv)
  86. }
  87. func (cd *CipherData) GetIV() uint64 {
  88. ivLen := len(cd.IV)
  89. return binary.BigEndian.Uint64(cd.IV[ivLen-8:])
  90. }
  91. func (cd *CipherData) SeekIV(startPos uint64) {
  92. cd.SetIV(cd.GetIV() + startPos/uint64(len(cd.IV)))
  93. }
  94. func (cd *CipherData) Clone() CipherData {
  95. var cloneCd CipherData
  96. cloneCd = *cd
  97. cloneCd.Key = make([]byte, len(cd.Key))
  98. copy(cloneCd.Key, cd.Key)
  99. cloneCd.IV = make([]byte, len(cd.IV))
  100. copy(cloneCd.IV, cd.IV)
  101. cloneCd.EncryptedIV = make([]byte, len(cd.EncryptedIV))
  102. copy(cloneCd.EncryptedIV, cd.EncryptedIV)
  103. cloneCd.EncryptedKey = make([]byte, len(cd.EncryptedKey))
  104. copy(cloneCd.EncryptedKey, cd.EncryptedKey)
  105. return cloneCd
  106. }