github.com/aldelo/common@v1.5.1/crypto/crypto.go (about) 1 package crypto 2 3 /* 4 * Copyright 2020-2023 Aldelo, LP 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 import ( 20 "crypto" 21 "crypto/aes" 22 "crypto/cipher" 23 "crypto/hmac" 24 "crypto/md5" 25 "crypto/rand" 26 "crypto/rsa" 27 "crypto/sha256" 28 "crypto/x509" 29 "encoding/pem" 30 "errors" 31 "fmt" 32 "hash/fnv" 33 "io" 34 "strings" 35 36 "golang.org/x/crypto/bcrypt" 37 "golang.org/x/crypto/scrypt" 38 39 util "github.com/aldelo/common" 40 "github.com/aldelo/common/ascii" 41 ) 42 43 // ================================================================================================================ 44 // KEY HELPERS 45 // ================================================================================================================ 46 47 // Generate32ByteRandomKey will generate a random 32 byte key based on passphrase and random salt, 48 // passphrase does not need to be any specific length 49 func Generate32ByteRandomKey(passphrase string) (string, error) { 50 // validate passphrase 51 if len(passphrase) == 0 { 52 return "", errors.New("Passphrase is Required") 53 } 54 55 // generate salt 56 salt := make([]byte, 32) 57 58 // populate salt 59 if _, err1 := io.ReadFull(rand.Reader, salt); err1 != nil { 60 return "", err1 61 } 62 63 // generate key 64 key, err2 := scrypt.Key([]byte(passphrase), salt, 32768, 8, 1, 32) 65 66 if err2 != nil { 67 return "", err2 68 } 69 70 return util.ByteToHex(key), nil 71 } 72 73 // ================================================================================================================ 74 // FNV HELPERS 75 // ================================================================================================================ 76 77 // FnvHashDigit returns persistent hash digit value, limited by the digit limit parameter 78 func FnvHashDigit(data string, digitLimit int) int { 79 h := fnv.New32a() 80 _, _ = h.Write([]byte(data)) 81 82 if digitLimit < 2 { 83 digitLimit = 2 84 } 85 86 return int(h.Sum32()%uint32(digitLimit-1) + 1) 87 } 88 89 // ================================================================================================================ 90 // MD5 HELPERS 91 // ================================================================================================================ 92 93 // Md5 hashing 94 func Md5(data string, salt string) string { 95 b := []byte(data + salt) 96 return fmt.Sprintf("%X", md5.Sum(b)) 97 } 98 99 // ================================================================================================================ 100 // SHA256 HELPERS 101 // ================================================================================================================ 102 103 // Sha256 hashing (always 64 bytes output) 104 func Sha256(data string, salt string) string { 105 b := []byte(data + salt) 106 return fmt.Sprintf("%X", sha256.Sum256(b)) 107 } 108 109 // ================================================================================================================ 110 // BCRYPT HELPERS 111 // ================================================================================================================ 112 113 // PasswordHash uses BCrypt to hash the given password and return a corresponding hash, 114 // suggested cost = 13 (440ms), 115 // if cost is left as 0, then default 13 is assumed 116 func PasswordHash(password string, cost int) (string, error) { 117 if cost <= 0 { 118 cost = 13 119 } else if cost < 12 { 120 cost = 12 121 } else if cost > 31 { 122 cost = 31 123 } 124 125 b, err := bcrypt.GenerateFromPassword([]byte(password), cost) 126 127 if err != nil { 128 return "", err 129 } 130 131 return string(b), nil 132 } 133 134 // PasswordVerify uses BCrypt to verify the input password against a prior hash version to see if match 135 func PasswordVerify(password string, hash string) (bool, error) { 136 err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) 137 138 if err != nil { 139 return false, err 140 } 141 142 return true, nil 143 } 144 145 // ================================================================================================================ 146 // AES-GCM HELPERS 147 // ================================================================================================================ 148 149 // AesGcmEncrypt will encrypt using aes gcm 256 bit, 150 // passphrase must be 32 bytes, if over 32 bytes, it be truncated, 151 // encrypted data is represented in hex value 152 func AesGcmEncrypt(data string, passphrase string) (string, error) { 153 // ensure data has value 154 if len(data) == 0 { 155 return "", errors.New("Data to Encrypt is Required") 156 } 157 158 // ensure passphrase is 32 bytes 159 // note: passphrase is just ascii, not hex, client should not convert to hex 160 if len(passphrase) < 32 { 161 return "", errors.New("Passphrase Must Be 32 Bytes") 162 } 163 164 // cut the passphrase to 32 bytes only 165 passphrase = util.Left(passphrase, 32) 166 167 // convert data and passphrase into byte array 168 text := []byte(data) 169 key := []byte(passphrase) 170 171 // generate a new aes cipher using the 32 bytes key 172 c, err1 := aes.NewCipher(key) 173 174 // on error stop 175 if err1 != nil { 176 return "", err1 177 } 178 179 // using gcm (Galois/Counter Mode) for symmetric key cryptographic block ciphers 180 // https://en.wikipedia.org/wiki/Galois/Counter_Mode 181 gcm, err2 := cipher.NewGCM(c) 182 183 // on error stop 184 if err2 != nil { 185 return "", err2 186 } 187 188 // create a new byte array the size of the nonce, 189 // which must be passed to Seal 190 nonce := make([]byte, gcm.NonceSize()) 191 192 // populate our nonce with a cryptographically secure random sequence 193 if _, err3 := io.ReadFull(rand.Reader, nonce); err3 != nil { 194 return "", err3 195 } 196 197 // encrypt our text using Seal function, 198 // Seal encrypts and authenticates plaintext, 199 // authenticates the additional data and appends the result to dst, 200 // returning the updated slice, 201 // the nonce must be NonceSize() bytes long and unique for all time, for a given key 202 203 // return util.ByteToHex(gcm.Seal(nonce, nonce, text, nil)), nil 204 return util.ByteToHex(gcm.Seal(nonce, nonce, text, nil)), nil 205 } 206 207 // AesGcmDecrypt will decrypt using aes gcm 256 bit, 208 // passphrase must be 32 bytes, if over 32 bytes, it be truncated 209 func AesGcmDecrypt(data string, passphrase string) (string, error) { 210 // ensure data has value 211 if len(data) == 0 { 212 return "", errors.New("Data to Decrypt is Required") 213 } 214 215 // ensure passphrase is 32 bytes 216 // note: passphrase is just ascii, not hex, client should not convert to hex 217 if len(passphrase) < 32 { 218 return "", errors.New("Passphrase Must Be 32 Bytes") 219 } 220 221 // cut the passphrase to 32 bytes only 222 passphrase = util.Left(passphrase, 32) 223 224 // convert data and passphrase into byte array 225 text, err := util.HexToByte(data) 226 227 if err != nil { 228 return "", err 229 } 230 231 key := []byte(passphrase) 232 233 // create aes cipher 234 c, err1 := aes.NewCipher(key) 235 236 // on error stop 237 if err1 != nil { 238 return "", err1 239 } 240 241 // create gcm (Galois/Counter Mode) to decrypt 242 gcm, err2 := cipher.NewGCM(c) 243 244 // on error stop 245 if err2 != nil { 246 return "", err2 247 } 248 249 // create nonce 250 nonceSize := gcm.NonceSize() 251 252 if len(text) < nonceSize { 253 return "", errors.New("Cipher Text Smaller Than Nonce Size") 254 } 255 256 // get cipher text 257 nonce, text := text[:nonceSize], text[nonceSize:] 258 259 // decrypt cipher text 260 plaintext, err3 := gcm.Open(nil, nonce, text, nil) 261 262 // on error stop 263 if err3 != nil { 264 return "", err3 265 } 266 267 // return decrypted text 268 return string(plaintext), nil 269 } 270 271 // ================================================================================================================ 272 // AES-CFB HELPERS 273 // ================================================================================================================ 274 275 // AesCfbEncrypt will encrypt using aes cfb 256 bit, 276 // passphrase must be 32 bytes, if over 32 bytes, it be truncated, 277 // encrypted data is represented in hex value 278 func AesCfbEncrypt(data string, passphrase string) (string, error) { 279 // ensure data has value 280 if len(data) == 0 { 281 return "", errors.New("Data to Encrypt is Required") 282 } 283 284 // ensure passphrase is 32 bytes 285 if len(passphrase) < 32 { 286 return "", errors.New("Passphrase Must Be 32 Bytes") 287 } 288 289 // cut the passphrase to 32 bytes only 290 passphrase = util.Left(passphrase, 32) 291 292 // convert data and passphrase into byte array 293 text := []byte(data) 294 key := []byte(passphrase) 295 296 // generate a new aes cipher using the 32 bytes key 297 c, err1 := aes.NewCipher(key) 298 299 // on error stop 300 if err1 != nil { 301 return "", err1 302 } 303 304 // iv needs to be unique, but doesn't have to be secure, 305 // its common to put it at the beginning of the cipher text 306 cipherText := make([]byte, aes.BlockSize+len(text)) 307 308 iv := cipherText[:aes.BlockSize] 309 310 if _, err2 := io.ReadFull(rand.Reader, iv); err2 != nil { 311 return "", err2 312 } 313 314 // encrypt 315 stream := cipher.NewCFBEncrypter(c, iv) 316 stream.XORKeyStream(cipherText[aes.BlockSize:], text) 317 318 // return encrypted data 319 return util.ByteToHex(cipherText), nil 320 } 321 322 // AesCfbDecrypt will decrypt using aes cfb 256 bit, 323 // passphrase must be 32 bytes, if over 32 bytes, it be truncated 324 func AesCfbDecrypt(data string, passphrase string) (string, error) { 325 // ensure data has value 326 if len(data) == 0 { 327 return "", errors.New("Data to Decrypt is Required") 328 } 329 330 // ensure passphrase is 32 bytes 331 if len(passphrase) < 32 { 332 return "", errors.New("Passphrase Must Be 32 Bytes") 333 } 334 335 // cut the passphrase to 32 bytes only 336 passphrase = util.Left(passphrase, 32) 337 338 // convert data and passphrase into byte array 339 text, err := util.HexToByte(data) 340 341 if err != nil { 342 return "", err 343 } 344 345 key := []byte(passphrase) 346 347 // create aes cipher 348 c, err1 := aes.NewCipher(key) 349 350 // on error stop 351 if err1 != nil { 352 return "", err1 353 } 354 355 // ensure cipher block size appropriate 356 if len(text) < aes.BlockSize { 357 return "", errors.New("Cipher Text Block Size Too Short") 358 } 359 360 // iv needs to be unique, doesn't have to secured, 361 // it's common to put iv at the beginning of the cipher text 362 iv := text[:aes.BlockSize] 363 text = text[aes.BlockSize:] 364 365 // decrypt 366 stream := cipher.NewCFBDecrypter(c, iv) 367 368 // XORKeyStream can work in-place if two arguments are the same 369 stream.XORKeyStream(text, text) 370 371 // return decrypted data 372 return string(text), nil 373 } 374 375 // ================================================================================================================ 376 // AES-CBC HELPERS 377 // ================================================================================================================ 378 379 // AesCbcEncrypt will encrypt using aes cbc 256 bit, 380 // passphrase must be 32 bytes, if over 32 bytes, it be truncated, 381 // encrypted data is represented in hex value 382 func AesCbcEncrypt(data string, passphrase string) (string, error) { 383 // ensure data has value 384 if len(data) == 0 { 385 return "", errors.New("Data to Encrypt is Required") 386 } 387 388 // ensure passphrase is 32 bytes 389 if len(passphrase) < 32 { 390 return "", errors.New("Passphrase Must Be 32 Bytes") 391 } 392 393 // cut the passphrase to 32 bytes only 394 passphrase = util.Left(passphrase, 32) 395 396 // in cbc, data must be in block size of aes (multiples of 16 bytes), 397 // otherwise padding needs to be performed 398 if len(data)%aes.BlockSize != 0 { 399 // pad with blank spaces up to 16 bytes 400 data = util.Padding(data, util.NextFixedLength(data, aes.BlockSize), true, ascii.AsciiToString(ascii.NUL)) 401 } 402 403 // convert data and passphrase into byte array 404 text := []byte(data) 405 key := []byte(passphrase) 406 407 // generate a new aes cipher using the 32 bytes key 408 c, err1 := aes.NewCipher(key) 409 410 // on error stop 411 if err1 != nil { 412 return "", err1 413 } 414 415 // iv needs to be unique, but doesn't have to be secure, 416 // its common to put it at the beginning of the cipher text 417 cipherText := make([]byte, aes.BlockSize+len(text)) 418 419 // create iv, length must be equal to block size 420 iv := cipherText[:aes.BlockSize] 421 422 if _, err2 := io.ReadFull(rand.Reader, iv); err2 != nil { 423 return "", err2 424 } 425 426 // encrypt 427 mode := cipher.NewCBCEncrypter(c, iv) 428 mode.CryptBlocks(cipherText[aes.BlockSize:], text) 429 430 // return encrypted data 431 return util.ByteToHex(cipherText), nil 432 } 433 434 // AesCbcDecrypt will decrypt using aes cbc 256 bit, 435 // passphrase must be 32 bytes, if over 32 bytes, it be truncated 436 func AesCbcDecrypt(data string, passphrase string) (string, error) { 437 // ensure data has value 438 if len(data) == 0 { 439 return "", errors.New("Data to Decrypt is Required") 440 } 441 442 // ensure passphrase is 32 bytes 443 if len(passphrase) < 32 { 444 return "", errors.New("Passphrase Must Be 32 Bytes") 445 } 446 447 // cut the passphrase to 32 bytes only 448 passphrase = util.Left(passphrase, 32) 449 450 // convert data and passphrase into byte array 451 text, err := util.HexToByte(data) 452 453 if err != nil { 454 return "", err 455 } 456 457 key := []byte(passphrase) 458 459 // create aes cipher 460 c, err1 := aes.NewCipher(key) 461 462 // on error stop 463 if err1 != nil { 464 return "", err1 465 } 466 467 // ensure cipher block size appropriate 468 if len(text) < aes.BlockSize { 469 return "", errors.New("Cipher Text Block Size Too Short") 470 } 471 472 // iv needs to be unique, doesn't have to secured, 473 // it's common to put iv at the beginning of the cipher text 474 iv := text[:aes.BlockSize] 475 text = text[aes.BlockSize:] 476 477 // cbc mode always work in whole blocks 478 if len(text)%aes.BlockSize != 0 { 479 return "", errors.New("Cipher Text Must Be In Multiple of Block Size") 480 } 481 482 // decrypt 483 mode := cipher.NewCBCDecrypter(c, iv) 484 mode.CryptBlocks(text, text) 485 486 // return decrypted data 487 return strings.ReplaceAll(string(text[:]), ascii.AsciiToString(ascii.NUL), ""), nil 488 } 489 490 // ================================================================================================================ 491 // HMAC HELPERS 492 // ================================================================================================================ 493 494 // AppendHmac will calculate the hmac for the given encrypted data based on the given key, 495 // and append the Hmac to the end of the encrypted data and return the newly assembled encrypted data with hmac 496 // key must be 32 bytes 497 func AppendHmac(encryptedData string, key string) (string, error) { 498 // ensure data has value 499 if len(encryptedData) == 0 { 500 return "", errors.New("Data is Required") 501 } 502 503 // ensure key is 32 bytes 504 if len(key) < 32 { 505 return "", errors.New("Key Must Be 32 Bytes") 506 } 507 508 data := []byte(encryptedData) 509 510 // cut the key to 32 bytes only 511 key = util.Left(key, 32) 512 513 // new hmac 514 macProducer := hmac.New(sha256.New, []byte(key)) 515 macProducer.Write(data) 516 517 // generate mac 518 strMac := util.ByteToHex(macProducer.Sum(nil)) 519 mac := []byte(strMac) 520 521 // append and return 522 return string(append(data, mac...)), nil 523 } 524 525 // ValidateHmac will verify if the appended hmac validates against the message based on the given key, 526 // and parse the hmac out and return the actual message if hmac validation succeeds, 527 // if hmac validation fails, then blank is returned and the error contains the failure reason 528 func ValidateHmac(encryptedDataWithHmac string, key string) (string, error) { 529 // ensure data has value 530 if len(encryptedDataWithHmac) <= 64 { // hex is 2x the byte, so 32 normally is now 64 531 return "", errors.New("Data with HMAC is Required") 532 } 533 534 // ensure key is 32 bytes 535 if len(key) < 32 { 536 return "", errors.New("Key Must Be 32 Bytes") 537 } 538 539 // cut the key to 32 bytes only 540 key = util.Left(key, 32) 541 542 // data to byte 543 data := []byte(encryptedDataWithHmac) 544 545 // parse message 546 message := data[:len(data)-64] 547 mac, err := util.HexToByte(string(data[len(data)-64:])) 548 549 if err != nil { 550 return "", err 551 } 552 553 // new mac 554 macProducer := hmac.New(sha256.New, []byte(key)) 555 macProducer.Write(message) 556 557 // get calculated mac 558 calculatedMac := macProducer.Sum(nil) 559 560 if hmac.Equal(mac, calculatedMac) { 561 // hmac match, return encrypted data without hmac 562 return string(message), nil 563 } 564 565 // if process gets here, then hmac failed 566 return "", errors.New("HMAC Verification Failed") 567 } 568 569 // ================================================================================================================ 570 // RSA HELPERS 571 // ================================================================================================================ 572 573 // RsaCreateKey generates the private and public key pair, 574 // expressed in hex code value 575 func RsaCreateKey() (privateKey string, publicKey string, err error) { 576 // generate new private key 577 rsaKey, err := rsa.GenerateKey(rand.Reader, 2048) 578 579 if err != nil { 580 return "", "", err 581 } 582 583 // get the public key 584 rsaPublicKey := &rsaKey.PublicKey 585 586 // get private key in bytes 587 bytesPrivateKey := pem.EncodeToMemory(&pem.Block{ 588 Type: "RSA PRIVATE KEY", 589 Bytes: x509.MarshalPKCS1PrivateKey(rsaKey)}) 590 591 // get public key in bytes 592 bytesPublicKey := pem.EncodeToMemory(&pem.Block{ 593 Type: "RSA PUBLIC KEY", 594 Bytes: x509.MarshalPKCS1PublicKey(rsaPublicKey)}) 595 596 // return result 597 return util.ByteToHex(bytesPrivateKey), util.ByteToHex(bytesPublicKey), nil 598 } 599 600 // rsaPrivateKeyFromHex converts hex string private key into rsa private key object 601 func rsaPrivateKeyFromHex(privateKeyHex string) (*rsa.PrivateKey, error) { 602 // convert hex to bytes 603 bytesPrivateKey, err := util.HexToByte(privateKeyHex) 604 605 if err != nil { 606 return nil, err 607 } 608 609 // convert byte to object 610 block, _ := pem.Decode(bytesPrivateKey) 611 612 if block == nil { 613 return nil, errors.New("RSA Private Key From Hex Fail: " + "Pem Block Nil") 614 } 615 616 enc := x509.IsEncryptedPEMBlock(block) 617 b := block.Bytes 618 619 if enc { 620 b, err = x509.DecryptPEMBlock(block, nil) 621 622 if err != nil { 623 return nil, err 624 } 625 } 626 627 // parse key 628 key, err1 := x509.ParsePKCS1PrivateKey(b) 629 630 if err1 != nil { 631 return nil, err1 632 } 633 634 // return private key 635 return key, nil 636 } 637 638 // rsaPrivateKeyFromPem converts pkcs1 string private key into rsa private key object 639 func rsaPrivateKeyFromPem(privateKeyPem string) (*rsa.PrivateKey, error) { 640 block, _ := pem.Decode([]byte(privateKeyPem)) 641 642 if block == nil { 643 return nil, errors.New("RSA Private Key From Pem Fail: " + "Pem Block Nil") 644 } 645 646 if key, err := x509.ParsePKCS1PrivateKey(block.Bytes); err != nil { 647 return nil, err 648 } else { 649 return key, nil 650 } 651 } 652 653 // rsaPublicKeyFromHex converts hex string public key into rsa public key object 654 func rsaPublicKeyFromHex(publicKeyHex string) (*rsa.PublicKey, error) { 655 // convert hex to bytes 656 bytesPublicKey, err := util.HexToByte(publicKeyHex) 657 658 if err != nil { 659 return nil, err 660 } 661 662 // convert byte to object 663 block, _ := pem.Decode(bytesPublicKey) 664 665 if block == nil { 666 return nil, errors.New("RSA Public Key From Hex Fail: " + "Pem Block Nil") 667 } 668 669 enc := x509.IsEncryptedPEMBlock(block) 670 b := block.Bytes 671 672 if enc { 673 b, err = x509.DecryptPEMBlock(block, nil) 674 675 if err != nil { 676 return nil, err 677 } 678 } 679 680 // parse key 681 key, err1 := x509.ParsePKCS1PublicKey(b) 682 683 if err1 != nil { 684 return nil, err1 685 } 686 687 // return public key 688 return key, nil 689 } 690 691 // rsaPublicKeyFromPem converts certificate string public key into rsa public key object 692 func rsaPublicKeyFromPem(publicKeyPem string) (*rsa.PublicKey, error) { 693 block, _ := pem.Decode([]byte(publicKeyPem)) 694 695 if block == nil { 696 return nil, errors.New("RSA Public Key From Pem Fail: " + "Pem Block Nil") 697 } 698 699 if key, err := x509.ParsePKIXPublicKey(block.Bytes); err != nil { 700 return nil, err 701 } else { 702 return key.(*rsa.PublicKey), nil 703 } 704 } 705 706 // RsaPublicKeyEncrypt will encrypt given data using rsa public key, 707 // encrypted data is represented in hex value 708 // 709 // publicKeyHexOrPem = can be either HEX or PEM 710 func RsaPublicKeyEncrypt(data string, publicKeyHexOrPem string) (string, error) { 711 // data must not exceed 214 bytes 712 if len(data) > 214 { 713 return "", errors.New("RSA Public Key Encrypt Data Must Not Exceed 214 Bytes") 714 } 715 716 if len(data) == 0 { 717 return "", errors.New("Data To Encrypt is Required") 718 } 719 720 // get public key 721 var publicKey *rsa.PublicKey 722 var err error 723 724 if util.Left(publicKeyHexOrPem, 26) == "-----BEGIN PUBLIC KEY-----" && util.Right(publicKeyHexOrPem, 24) == "-----END PUBLIC KEY-----" { 725 // get public key from pem 726 publicKey, err = rsaPublicKeyFromPem(publicKeyHexOrPem) 727 } else { 728 // get public key from hex 729 publicKey, err = rsaPublicKeyFromHex(publicKeyHexOrPem) 730 } 731 732 if err != nil { 733 return "", err 734 } 735 736 // convert data into byte array 737 msg := []byte(data) 738 739 // create hash 740 hash := sha256.New() 741 742 // encrypt 743 cipherText, err1 := rsa.EncryptOAEP(hash, rand.Reader, publicKey, msg, nil) 744 745 if err1 != nil { 746 return "", err1 747 } 748 749 // return encrypted value 750 return util.ByteToHex(cipherText), nil 751 } 752 753 // RsaPrivateKeyDecrypt will decrypt rsa public key encrypted data using its corresponding rsa private key 754 // 755 // privateKeyHexOrPem = can be either HEX or PEM 756 func RsaPrivateKeyDecrypt(data string, privateKeyHexOrPem string) (string, error) { 757 // data to decrypt must exist 758 if len(data) == 0 { 759 return "", errors.New("Data To Decrypt is Required") 760 } 761 762 // get private key 763 var privateKey *rsa.PrivateKey 764 var err error 765 766 if util.Left(privateKeyHexOrPem, 27) == "-----BEGIN PRIVATE KEY-----" && util.Right(privateKeyHexOrPem, 25) == "-----END PRIVATE KEY-----" { 767 // get private key from pem text 768 privateKey, err = rsaPrivateKeyFromPem(privateKeyHexOrPem) 769 } else { 770 // get private key from hex 771 privateKey, err = rsaPrivateKeyFromHex(privateKeyHexOrPem) 772 } 773 774 if err != nil { 775 return "", err 776 } 777 778 // convert hex data into byte array 779 msg, err1 := util.HexToByte(data) 780 781 if err1 != nil { 782 return "", err1 783 } 784 785 // create hash 786 hash := sha256.New() 787 788 // decrypt 789 plainText, err2 := rsa.DecryptOAEP(hash, rand.Reader, privateKey, msg, nil) 790 791 if err2 != nil { 792 return "", err2 793 } 794 795 // return decrypted value 796 return string(plainText), nil 797 } 798 799 // RsaPrivateKeySign will sign the plaintext data using the given private key, 800 // NOTE: data must be plain text before encryption as signature verification is against plain text data 801 // signature is returned via hex 802 // 803 // privateKeyHexOrPem = can be either HEX or PEM 804 func RsaPrivateKeySign(data string, privateKeyHexOrPem string) (string, error) { 805 // data is required 806 if len(data) == 0 { 807 return "", errors.New("Data To Sign is Required") 808 } 809 810 // get private key 811 var privateKey *rsa.PrivateKey 812 var err error 813 814 if util.Left(privateKeyHexOrPem, 27) == "-----BEGIN PRIVATE KEY-----" && util.Right(privateKeyHexOrPem, 25) == "-----END PRIVATE KEY-----" { 815 // get private key from pem text 816 privateKey, err = rsaPrivateKeyFromPem(privateKeyHexOrPem) 817 } else { 818 privateKey, err = rsaPrivateKeyFromHex(privateKeyHexOrPem) 819 } 820 821 if err != nil { 822 return "", err 823 } 824 825 // convert data to byte array 826 msg := []byte(data) 827 828 // define hash 829 h := sha256.New() 830 h.Write(msg) 831 d := h.Sum(nil) 832 833 signature, err1 := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, d) 834 835 if err1 != nil { 836 return "", err1 837 } 838 839 // return signature 840 return util.ByteToHex(signature), nil 841 } 842 843 // RsaPublicKeyVerify will verify the plaintext data using the given public key, 844 // NOTE: data must be plain text before encryption as signature verification is against plain text data 845 // if verification is successful, nil is returned, otherwise error is returned 846 // 847 // publicKeyHexOrPem = can be either HEX or PEM 848 func RsaPublicKeyVerify(data string, publicKeyHexOrPem string, signatureHex string) error { 849 // data is required 850 if len(data) == 0 { 851 return errors.New("Data To Verify is Required") 852 } 853 854 // get public key 855 var publicKey *rsa.PublicKey 856 var err error 857 858 if util.Left(publicKeyHexOrPem, 26) == "-----BEGIN PUBLIC KEY-----" && util.Right(publicKeyHexOrPem, 24) == "-----END PUBLIC KEY-----" { 859 // get public key from pem 860 publicKey, err = rsaPublicKeyFromPem(publicKeyHexOrPem) 861 } else { 862 // get public key from hex 863 publicKey, err = rsaPublicKeyFromHex(publicKeyHexOrPem) 864 } 865 866 if err != nil { 867 return err 868 } 869 870 // convert data to byte array 871 msg := []byte(data) 872 873 // define hash 874 h := sha256.New() 875 h.Write(msg) 876 d := h.Sum(nil) 877 878 sig, _ := util.HexToByte(signatureHex) 879 880 err1 := rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, d, sig) 881 882 if err1 != nil { 883 return err1 884 } 885 886 // verified 887 return nil 888 } 889 890 // RsaPublicKeyEncryptAndPrivateKeySign will encrypt given data using recipient's rsa public key, 891 // and then using sender's rsa private key to sign, 892 // NOTE: data represents the plaintext data, 893 // encrypted data and signature are represented in hex values 894 // 895 // recipientPublicKeyHexOrPem = can be either HEX or PEM 896 // senderPrivateKeyHexOrPem = can be either HEX or PEM 897 func RsaPublicKeyEncryptAndPrivateKeySign(data string, recipientPublicKeyHexOrPem string, senderPrivateKeyHexOrPem string) (encryptedData string, signature string, err error) { 898 encryptedData, err = RsaPublicKeyEncrypt(data, recipientPublicKeyHexOrPem) 899 900 if err != nil { 901 encryptedData = "" 902 return "", "", err 903 } 904 905 signature, err = RsaPrivateKeySign(data, senderPrivateKeyHexOrPem) 906 907 if err != nil { 908 encryptedData = "" 909 signature = "" 910 return "", "", err 911 } 912 913 // return success values 914 return encryptedData, signature, nil 915 } 916 917 // RsaPrivateKeyDecryptAndPublicKeyVerify will decrypt given data using recipient's rsa private key, 918 // and then using sender's rsa public key to verify if the signature given is a match, 919 // NOTE: data represents the encrypted data 920 // 921 // recipientPrivateKeyHexOrPem = can be either HEX or PEM 922 // senderPublicKeyHexOrPem = can be either HEX or PEM 923 func RsaPrivateKeyDecryptAndPublicKeyVerify(data string, recipientPrivateKeyHexOrPem string, signatureHex string, senderPublicKeyHexOrPem string) (plaintext string, verified bool, err error) { 924 plaintext, err = RsaPrivateKeyDecrypt(data, recipientPrivateKeyHexOrPem) 925 926 if err != nil { 927 plaintext = "" 928 return "", false, err 929 } 930 931 err = RsaPublicKeyVerify(plaintext, senderPublicKeyHexOrPem, signatureHex) 932 933 if err != nil { 934 plaintext = "" 935 verified = false 936 return "", false, err 937 } 938 939 // return success values 940 return plaintext, true, nil 941 } 942 943 // ================================================================================================================ 944 // RSA+AES DYNAMIC ENCRYPT/DECRYPT HELPERS 945 // ================================================================================================================ 946 947 // RsaAesPublicKeyEncryptAndSign is a simplified wrapper method to generate a random AES key, then encrypt plainText using AES GCM, 948 // and then sign plain text data using sender's private key, 949 // and then using recipient's public key to encrypt the dynamic aes key, 950 // and finally compose the encrypted payload that encapsulates a full envelop: 951 // 952 // <STX>RsaPublicKeyEncryptedAESKeyData + AesGcmEncryptedPayload(PlainTextData<VT>SenderPublicKey<VT>PlainTextDataSignature)<ETX> 953 // 954 // warning: VT is used in encrypted payload as separator, make sure to escape VT if it is to be used inside the plainTextData <<< IMPORTANT 955 // 956 // recipientPublicKeyHexOrPem = can be either HEX or PEM 957 // senderPublicKeyHexOrPem = can be either HEX or PEM 958 // senderPrivateKeyHexOrPem = can be either HEX or PEM 959 func RsaAesPublicKeyEncryptAndSign(plainText string, recipientPublicKeyHexOrPem string, senderPublicKeyHexOrPem string, senderPrivateKeyHexOrPem string) (encryptedData string, err error) { 960 // validate inputs 961 if util.LenTrim(plainText) == 0 { 962 return "", errors.New("Data To Encrypt is Required") 963 } 964 965 if util.LenTrim(recipientPublicKeyHexOrPem) == 0 { 966 return "", errors.New("Recipient Public Key is Required") 967 } 968 969 if util.LenTrim(senderPublicKeyHexOrPem) == 0 { 970 return "", errors.New("Sender Public Key is Required") 971 } 972 973 if util.LenTrim(senderPrivateKeyHexOrPem) == 0 { 974 return "", errors.New("Sender Private Key is Required") 975 } 976 977 // 978 // generate random aes key for data encryption during this session 979 // 980 aesKey, err1 := Generate32ByteRandomKey(Sha256(util.NewUUID(), util.CurrentDateTime())) 981 982 if err1 != nil { 983 return "", errors.New("Dynamic AES New Key Error: " + err1.Error()) 984 } 985 986 // 987 // rsa sender private key sign plain text data 988 // 989 signature, err2 := RsaPrivateKeySign(plainText, senderPrivateKeyHexOrPem) 990 991 if err2 != nil { 992 return "", errors.New("Dynamic AES Siganture Error: " + err2.Error()) 993 } 994 995 // 996 // encrypt plain text data using aes key with aes gcm, 997 // note: payload format = plainText<VT>senderPublicKeyHex<VT>plainTextSignature 998 // 999 aesEncryptedData, err3 := AesGcmEncrypt(plainText+ascii.AsciiToString(ascii.VT)+senderPublicKeyHexOrPem+ascii.AsciiToString(ascii.VT)+signature, aesKey) 1000 1001 if err3 != nil { 1002 return "", errors.New("Dynamic AES Data Encrypt Error: " + err3.Error()) 1003 } 1004 1005 // 1006 // now protect the aesKey with recipient's public key using rsa encrypt 1007 // 1008 aesEncryptedKey, err4 := RsaPublicKeyEncrypt(aesKey, recipientPublicKeyHexOrPem) 1009 1010 if err4 != nil { 1011 return "", errors.New("Dynamic AES Key Encrypt Error: " + err4.Error()) 1012 } 1013 1014 // 1015 // compose output encrypted payload 1016 // note: aesEncryptedKey_512_Bytes_Always + aesEncryptedData_Variable_Bytes + 64BytesRecipientPublicKeyHashWithSalt of 'TPK@2019' (TPK@2019 doesn't represent anything, just for backward compatibility in prior encrypted data) 1017 // parse first 512 bytes of payload = aes encrypted key (use recipient rsa private key to decrypt) 1018 // parse rest other than first 512 bytes of payload = aes encrypted data, using aes key to decrypt, contains plaintext<VT>senderPublicKey<VT>siganture 1019 // 1020 encryptedPayload := ascii.AsciiToString(ascii.STX) + aesEncryptedKey + aesEncryptedData + Sha256(recipientPublicKeyHexOrPem, "TPK@2019") + ascii.AsciiToString(ascii.ETX) // wrap in STX and ETX envelop to denote start and end of the encrypted payload 1021 1022 // 1023 // send encrypted payload data to caller 1024 // 1025 return encryptedPayload, nil 1026 } 1027 1028 // RsaAesParseTPKHashFromEncryptedPayload will get the public key TPK hash from the embedded encrypted data string 1029 func RsaAesParseTPKHashFromEncryptedPayload(encryptedData string) string { 1030 // strip STX and ETX out 1031 data := util.Right(encryptedData, len(encryptedData)-1) 1032 data = util.Left(data, len(data)-1) 1033 1034 // last 64 bytes of the encrypted data is the public key hash 1035 data = util.Right(data, 64) 1036 1037 // get actual tpk key 1038 return data 1039 } 1040 1041 // RsaAesPrivateKeyDecryptAndVerify is a simplified wrapper method to decrypt incoming encrypted payload envelop that was previously encrypted using the RsaAesPublicKeyEncryptAndSign(), 1042 // this function will use recipient's private key to decrypt the rsa encrypted dynamic aes key and then using the dynamic aes key to decrypt the aes encrypted data payload, 1043 // this function will then parse the decrypted payload and perform a verification of signature using the sender's public key 1044 // 1045 // usage tip: the sender's public key can then be used to encrypt the return data back to the sender as a reply using RsaAesPublicKeyEncryptedAndSign(), 1046 // 1047 // in this usage pattern, only the public key is used in each messaging cycle, while the aes key is dynamically generated each time and no prior knowledge of it is known, 1048 // since the public key encrypted data cannot be decrypted unless with private key, then as long as the private key is protected, then the messaging pipeline will be secured, 1049 // furthermore, by using sender private key sign and sender public key verify into the message authentication, we further ensure the plain text data is coming from the expected source 1050 // 1051 // recipientPrivateKeyHexOrPem = can be either HEX or PEM 1052 func RsaAesPrivateKeyDecryptAndVerify(encryptedData string, recipientPrivateKeyHexOrPem string) (plainText string, senderPublicKeyHexOrPem string, err error) { 1053 // validate inputs 1054 if util.LenTrim(encryptedData) <= 578 { 1055 return "", "", errors.New("Encrypted Payload Envelop Not Valid: Must Exceed 578 Bytes") 1056 } 1057 1058 if util.Left(encryptedData, 1) != ascii.AsciiToString(ascii.STX) { 1059 return "", "", errors.New("Encrypted Payload Envelop Not Valid: No STX Found") 1060 } 1061 1062 if util.Right(encryptedData, 1) != ascii.AsciiToString(ascii.ETX) { 1063 return "", "", errors.New("Encrypted Payload Envelop Not Valid: No ETX Found") 1064 } 1065 1066 if util.LenTrim(recipientPrivateKeyHexOrPem) == 0 { 1067 return "", "", errors.New("Recipient Private Key is Required") 1068 } 1069 1070 // strip STX and ETX out 1071 data := util.Right(encryptedData, len(encryptedData)-1) 1072 data = util.Left(data, len(data)-1) 1073 1074 // parse rsa public key encrypted aes key data 1075 aesKeyEncrypted := util.Left(data, 512) 1076 1077 // parse aes key encrypted data 1078 aesDataEncrypted := util.Right(data, len(data)-512) 1079 1080 // parse tpk hash from aes encrypted data 1081 // we don't need the tpk hash for the purpose of this method call 1082 // the tpk hash is only used by extracting and matching registry of keys and is used outside of this decrypter 1083 aesDataEncrypted = util.Left(aesDataEncrypted, len(aesDataEncrypted)-64) 1084 1085 // 1086 // decrypt aes key encrypted using rsa private key of recipient 1087 // 1088 aesKey, err1 := RsaPrivateKeyDecrypt(aesKeyEncrypted, recipientPrivateKeyHexOrPem) 1089 1090 if err1 != nil { 1091 return "", "", errors.New("Decrypt AES Key Error: " + err1.Error()) 1092 } 1093 1094 // 1095 // decrypt aes data using aes key that was just decrypted 1096 // 1097 aesData, err2 := AesGcmDecrypt(aesDataEncrypted, aesKey) 1098 1099 if err2 != nil { 1100 return "", "", errors.New("Decrypt AES Data Error: " + err2.Error()) 1101 } 1102 1103 if util.LenTrim(aesData) <= 1028 { 1104 return "", "", errors.New("Decrypted AES Data Not Valid: " + "Expected More Bytes") 1105 } 1106 1107 // 1108 // parse decrypted data into elements using VT as separator 1109 // expects 3 parts exactly 1110 // 1111 parts := strings.Split(aesData, ascii.AsciiToString(ascii.VT)) 1112 1113 if len(parts) != 3 { 1114 return "", "", errors.New("Decrypted AES Data Not Valid: " + "Expected 3 Parts Exactly, " + util.Itoa(len(parts)) + " Parts Returned Instead" + aesData) 1115 } 1116 1117 plainText = parts[0] 1118 senderPublicKeyHexOrPem = parts[1] 1119 signature := parts[2] 1120 1121 if util.LenTrim(plainText) == 0 { 1122 plainText = "" 1123 senderPublicKeyHexOrPem = "" 1124 1125 return "", "", errors.New("Decrypted AES Data Not Valid: " + "Empty String Not Expected") 1126 } 1127 1128 if util.LenTrim(senderPublicKeyHexOrPem) < 512 { 1129 plainText = "" 1130 senderPublicKeyHexOrPem = "" 1131 1132 return "", "", errors.New("Decrypted AES Data Not Valid: " + "Sender Public Key Not Complete") 1133 } 1134 1135 if util.LenTrim(signature) < 512 { 1136 plainText = "" 1137 senderPublicKeyHexOrPem = "" 1138 1139 return "", "", errors.New("Decrypted AES Data Not Valid: " + "Sender Signature Not Complete") 1140 } 1141 1142 // 1143 // verify plain text data against signature using sender public key hex 1144 // 1145 if err3 := RsaPublicKeyVerify(plainText, senderPublicKeyHexOrPem, signature); err3 != nil { 1146 plainText = "" 1147 senderPublicKeyHexOrPem = "" 1148 1149 return "", "", errors.New("Decrypted AES Data Not Valid: (Signature Not Authenticated) " + err3.Error()) 1150 } 1151 1152 // 1153 // decrypt completed successful 1154 // 1155 return plainText, senderPublicKeyHexOrPem, nil 1156 }