├── README.md ├── public.pem ├── .gitignore ├── test └── test.go ├── private.pem ├── LICENSE └── rsa └── rsa.go /README.md: -------------------------------------------------------------------------------- 1 | rsa 2 | === 3 | 4 | 实现RSA公钥解密和私钥加密 5 | 6 | ## Installation 7 | 8 | go get github.com/dgkang/rsa/rsa 9 | 10 | -------------------------------------------------------------------------------- /public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7stGsJGuVBp4usw858mCZTzY2 3 | c81xV5gaYgCKZC22THD47yr0+AnWLZrc02lX02YKlCzZVq586TE9AJqBC/qFCGBS 4 | kKwyoS0esFKVVIIPp6GZOe3ZpaxdEKB1jlXoEjN9+CFmc5CIphk1+rWgfbia+FxJ 5 | hJ8byPiGwaCYZe6ekQIDAQAB 6 | -----END PUBLIC KEY----- 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | -------------------------------------------------------------------------------- /test/test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "os" 4 | import "log" 5 | import "io/ioutil" 6 | import "github.com/dgkang/rsa/rsa" 7 | import "fmt" 8 | 9 | func main() { 10 | file, err := os.Open("./test.txt") 11 | if err != nil { 12 | log.Fatal(err) 13 | } 14 | b, e := ioutil.ReadAll(file) 15 | if e != nil { 16 | log.Fatal(e) 17 | } 18 | 19 | brsa, e := rsa.PrivateEncrypt(b, "./private.pem", rsa.RSA_PKCS1_PADDING) 20 | if e != nil { 21 | fmt.Printf("%s\n", e.Error()) 22 | return 23 | } 24 | ioutil.WriteFile("./public.rsa", brsa, os.ModePerm) 25 | 26 | buf, e := rsa.PublicDecrypt(brsa, "./public.pem", rsa.RSA_PKCS1_PADDING) 27 | if e == nil { 28 | fmt.Printf("Decrypt: %s", string(buf)) 29 | } else { 30 | fmt.Printf("%s\n", e.Error()) 31 | return 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXAIBAAKBgQC7stGsJGuVBp4usw858mCZTzY2c81xV5gaYgCKZC22THD47yr0 3 | +AnWLZrc02lX02YKlCzZVq586TE9AJqBC/qFCGBSkKwyoS0esFKVVIIPp6GZOe3Z 4 | paxdEKB1jlXoEjN9+CFmc5CIphk1+rWgfbia+FxJhJ8byPiGwaCYZe6ekQIDAQAB 5 | AoGARafR2eFWL2LaVxhKQUXqhVp5EvIcvsA0CS5vZuxQboOltSwEtA5MkDgybVrj 6 | kB06lBhzIGDjtiVQCYRs0hEg8ZTt+uaR8bmG6uQViXMZxBF/Q4JCuBS8fg5MZvN3 7 | eXAoCLszHjWNFu5tTeuMsWlzP5bFE3SL5n2KYgqRluno2AECQQDhE/Kv1aXxrLBJ 8 | XRQHZKl7rkeEa6JGuvVto+6JtTINmCoAakELs8LOvseJySlmlwnVG5J6WxJhiqjt 9 | Ps7Td8WBAkEA1Xw6GwmODIiADdel505lM1YNSQbJQ+1zBHDV9q0vaAd+P2X0pz8B 10 | fGg6KRwS/NoARRDBt6JDmNQWeEt/v7UBEQJAQ80ciDdVu82HdTIivG9oVqeTR6Kc 11 | ya28DQEa9ESvBUVXMbTQT1QhVOJHfYwpeov5HEcoAs+4Y8W/SWhoKW+lAQJARTcB 12 | n8J5S5b17Yb9QwEnzn0X0ZVhq6RQph/vPwrnU9MaG3Py3kaPNMaWFL4FafVEISBN 13 | rjvtrp8UqevQf1cwAQJBANVN3P5Nh94vt/4i21EigxiIHjdRjNNZQbkwWDzkzANI 14 | TYApjguEdbJ2ROJmQkJU0STuHrvlDozqPAnB4FmR0dQ= 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Cheng Shao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /rsa/rsa.go: -------------------------------------------------------------------------------- 1 | package rsa 2 | 3 | /* 4 | #cgo LDFLAGS: -lssl -lcrypto 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | char last_error_string[2048] = {0}; 14 | 15 | RSA* rsa_read_pem_public(char* pem){ 16 | FILE * fp = fopen(pem,"r"); 17 | if(fp == NULL){ 18 | snprintf(last_error_string,sizeof(last_error_string),"open \"%s\" failed",pem); 19 | return NULL; 20 | } 21 | 22 | RSA * public_key = RSA_new(); 23 | 24 | if (!PEM_read_RSA_PUBKEY(fp, &public_key, NULL, NULL)){ 25 | snprintf(last_error_string,sizeof(last_error_string),"%s",ERR_error_string(ERR_get_error(),NULL)); 26 | RSA_free(public_key); 27 | return NULL; 28 | } 29 | return public_key; 30 | } 31 | 32 | RSA* rsa_read_pem_private(char* pem){ 33 | FILE * fp = fopen(pem,"r"); 34 | if(fp == NULL){ 35 | snprintf(last_error_string,sizeof(last_error_string),"open \"%s\" failed",pem); 36 | return NULL; 37 | } 38 | RSA * private_key = RSA_new(); 39 | 40 | if (!PEM_read_RSAPrivateKey(fp, &private_key, NULL, NULL)){ 41 | snprintf(last_error_string,sizeof(last_error_string),"%s",ERR_error_string(ERR_get_error(),NULL)); 42 | RSA_free(private_key); 43 | return NULL; 44 | } 45 | return private_key; 46 | } 47 | 48 | int rsa_private_encrypt(int fromSize,unsigned char *from,char** to, char* pem, int padding){ 49 | RSA* private_key = rsa_read_pem_private(pem); 50 | if(!private_key){ 51 | return -1; 52 | } 53 | *to = (char*)malloc(sizeof(char) * RSA_size(private_key)); 54 | int n = RSA_private_encrypt(fromSize,from,(unsigned char *)*to,private_key,padding); 55 | if (n == -1){ 56 | snprintf(last_error_string,sizeof(last_error_string),"%s",ERR_error_string(ERR_get_error(),NULL)); 57 | } 58 | RSA_free(private_key); 59 | return n; 60 | } 61 | 62 | int rsa_public_decrypt(int fromSize,unsigned char *from,char** to, char* pem, int padding){ 63 | RSA* public_key = rsa_read_pem_public(pem); 64 | if(!public_key){ 65 | return -1; 66 | } 67 | *to = (char*)malloc(sizeof(char) * RSA_size(public_key)); 68 | int n = RSA_public_decrypt(fromSize,from,(unsigned char *)*to,public_key,padding); 69 | if (n == -1){ 70 | snprintf(last_error_string,sizeof(last_error_string),"%s",ERR_error_string(ERR_get_error(),NULL)); 71 | } 72 | RSA_free(public_key); 73 | return n; 74 | 75 | } 76 | */ 77 | import "C" 78 | import "unsafe" 79 | import "fmt" 80 | 81 | const ( 82 | RSA_PKCS1_PADDING = C.RSA_PKCS1_PADDING 83 | RSA_NO_PADDING = C.RSA_NO_PADDING 84 | ) 85 | 86 | func PublicDecrypt(from []byte, pem string, padding int) ([]byte, error) { 87 | var to *C.char = nil 88 | 89 | if n := C.rsa_public_decrypt(C.int(len(from)), 90 | (*C.uchar)(unsafe.Pointer(&from[0])), 91 | //(*C.uchar)(unsafe.Pointer(&to[0])), 92 | (**C.char)(unsafe.Pointer(&to)), 93 | C.CString(pem), 94 | C.int(padding)); n < 0 { 95 | return nil, fmt.Errorf("%s", C.GoString(&C.last_error_string[0])) 96 | } else { 97 | m := C.GoBytes(unsafe.Pointer(to), n) 98 | C.free(unsafe.Pointer(to)) 99 | return m, nil 100 | } 101 | } 102 | 103 | func PrivateEncrypt(from []byte, pem string, padding int) ([]byte, error) { 104 | var to *C.char = nil 105 | 106 | if n := C.rsa_private_encrypt(C.int(len(from)), 107 | (*C.uchar)(unsafe.Pointer(&from[0])), 108 | (**C.char)(unsafe.Pointer(&to)), 109 | //(*C.uchar)(unsafe.Pointer(&to[0])), 110 | C.CString(pem), 111 | C.int(padding)); n < 0 { 112 | return nil, fmt.Errorf("%s", C.GoString(&C.last_error_string[0])) 113 | } else { 114 | m := C.GoBytes(unsafe.Pointer(to), n) 115 | C.free(unsafe.Pointer(to)) 116 | return m, nil 117 | } 118 | } 119 | /* 120 | func Destroy() { 121 | C.ERR_free_strings() 122 | } 123 | 124 | func init() { 125 | C.ERR_load_crypto_strings() 126 | } 127 | */ 128 | --------------------------------------------------------------------------------