openssl在多平台和多语言之间进行RSA加解密注意事项

首先说一下平台和语言:

系统平台为CentOS6.3,RSA加解密时使用NOPADDING进行填充

1)使用C/C++调用系统自带的openssl

2)Android4.2模拟器,第三方openssl(android-external-openssl-master),使用ndk编译静态库,然后使用C/C++进行调用

3)使用Java自身的类库(javax.crypto和java.security)

 

在linux下,使用如下命令,生成RSA加解密时使用的public和private的key

openssl genrsa -out rsa_private_key.pem 1024  //生成私钥

openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout   //生成公钥

openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt  //转化成PKCS#8编码编码,供Java解密时,进行调用

我在目录中创建一个hello的文本文件,然后利用此前生成的公钥加密文件

openssl rsautl -encrypt -in hello -inkey test_pub.key -pubin -out hello.en 

-in指定要加密的文件,-inkey指定密钥,-pubin表明是用纯公钥文件加密,-out为加密后的文件。

解密文件:

openssl rsautl -decrypt -in hello.en -inkey test.key -out hello.de

-in指定被加密的文件,-inkey指定私钥文件,-out为解密后的文件。


 

假如我们要对字符串"12345678”进行加解密

1)C/C++调用系统自带的openssl加解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
//============================================================================
// Name        : HelloPlus.cpp
// Author      :
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//#include <iostream>
#include <sys/types.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
 
#define PUBSSLKEY "rsa_public_key.pem"
#define PRISSLKEY "rsa_private_key.pem"
#define BUFFSIZE 1024
#define MAX_PATH 256
 
pid_t get_pid_from_proc_self();
char * get_self_executable_directory();
unsignedchar *my_encrypt(unsignedchar *str,char *pubPath,char *priPath);
unsignedchar *byteArrayToString(unsignedchar *data,int dataLen);
 
//using namespace std;
 
unsignedchar *encode64(unsignedchar *data,int dataLen)
{
    /*
    char base64code[] = {
        'A','B','C','D','E','F','G','H','I','J','K','L','M','N'\
        ,'O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b'\
        ,'c','d','e','f','g','h','i','j','k','l','m','n','o','p'\
        ,'q','r','s','t','u','v','w','x','y','z','0','1','2','3'\
        ,'4','5','6','7','8','9','+','/'};
    */
    //char base64code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmlopqrstuvwxyz0123456789+/";
    unsignedchar *base64code = (unsigned char*)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmlopqrstuvwxyz0123456789+/";
    int times = dataLen%3;
    int page = dataLen/3;
 
    unsignedchar *outData = (unsigned char*)malloc(4 * (page + 1) + 1);
    memset(outData,0,4 * (page + 1) + 1);
 
    unsignedchar buff[3];
    unsignedchar instr[4] = {0};
    unsignedchar *ptr = data;
    unsignedchar *outPtr = outData;
    for(int i = 0; i < page; i++)
    {
        memset(buff,0,3);
        memcpy(buff,ptr,3);
        ptr += 3;
 
        instr[0] = buff[0] >> 2;
        instr[1] = (buff[0] & 0x03) << 4 | buff[1] >> 4;
        instr[2] = (buff[1] & 0x0f << 2) | buff[2] >> 6;
        instr[3] = buff[2] & 0x3f;
                 
        *outPtr++ = base64code[instr[0]];
        *outPtr++ = base64code[instr[1]];
        *outPtr++ = base64code[instr[2]];
        *outPtr++ = base64code[instr[3]];
    }
    int mod = dataLen%3;
    if(mod == 1)
    {
        buff[0] = *ptr;
        *outPtr++ = base64code[buff[0] >> 2];
        *outPtr++ = base64code[(buff[0] & 0x03) << 4 ];
        *outPtr++ = '=';
        *outPtr++ = '=';
    }
    else if(mod == 2)
    {
        buff[0] = *ptr++;
        buff[1] = *ptr;
        *outPtr++ = base64code[buff[0] >> 2];
        *outPtr++ = base64code[((buff[0] & 0x03) << 4) | (buff[1] >> 4)];
        *outPtr++ = base64code[(buff[1] & 0x0f) << 2];
        *outPtr++ = '=';
    }
    return outData;
}
 
unsignedchar *char2hex(unsignedchar *data,int dataLen)
{
    unsignedchar *tmp = (unsigned char*)malloc(dataLen * 2 + 1);
    memset(tmp,0,dataLen * 2 + 1);
    char *ptr = (char*)tmp;
    for(int i = 0; i < dataLen; i++)
    {
        sprintf(ptr,"%02X",data[i]);
        ptr += 2;
    }
    return tmp;
}
 
unsignedchar *my_encrypt(unsignedchar *str,char *pubPath,char *priPath)
{
    unsignedchar *p_en;
    RSA *p_rsa;
    FILE *file;
    int flen,rsa_len;
 
     
    if((file = fopen(pubPath,"r")) == NULL) {
        perror("open pub key file error");
        return NULL;
    }
     
 
    /* 
    BIO *key = NULL;
    key = BIO_new(BIO_s_file());
    BIO_read_filename(key,pubPath);
    if((p_rsa = PEM_read_bio_RSA_PUBKEY(key,NULL,NULL,NULL)) == NULL) {
    //if((p_rsa = PEM_read_bio_RSAPrivateKey(key,NULL,NULL,NULL)) == NULL) {
        ERR_print_errors_fp(stdout);
        BIO_free_all(key);
        return NULL;
    }
    */
 
     
    if((p_rsa = PEM_read_RSA_PUBKEY(file,NULL,NULL,NULL)) == NULL) {
        ERR_print_errors_fp(stdout);
        return NULL;
    }
     
 
    /* 
    BIO *bio;
    X509 *centificate;
    bio = BIO_new(BIO_s_file());
    BIO_read_filename(bio,keyPath);
    centificate = PEM_read_bio_X509(bio,NULL,NULL,NULL);
    EVP_PKEY *pubKey = X509_get_pubkey(centificate);
    RSA *rsa_pkey = EVP_PKEY_get1_RSA(pubKey);
 
    if(!PEM_read_RSAPublicKey(file,&rsa_pkey,NULL,NULL))
    {
        ERR_print_errors_fp(stdout);
        return NULL;
    }
    */ 
 
    flen = strlen((char*)str);
    rsa_len = RSA_size(p_rsa);
    p_en = (unsigned char *)malloc(rsa_len + 1);
    memset(p_en,0,rsa_len + 1);
    int iret = RSA_public_encrypt(rsa_len,str,p_en,p_rsa,RSA_NO_PADDING);
    if(iret < 0)
    {
        return NULL;
    }
    RSA_free(p_rsa);
    fclose(file);
     
    if((file = fopen(priPath,"r")) == NULL) {
        perror("open key file error");
        return NULL;
    }
 
     
    if((p_rsa = PEM_read_RSAPrivateKey(file,NULL,NULL,NULL)) == NULL) {
        ERR_print_errors_fp(stdout);
        return NULL;
    }
 
    unsignedchar p_de[1024] = {0};
    iret = RSA_private_decrypt(iret,p_en,p_de,p_rsa,RSA_NO_PADDING);
    if(iret < 0)
        return NULL;
 
    printf("content is [%s]\n",p_de);
    RSA_free(p_rsa);
    fclose(file);
     
    return p_en;
}
 
pid_t get_pid_from_proc_self()
{
    char target[32];
    int pid;
    readlink("/proc/self",target,sizeof(target));
    sscanf(target,"%d",&pid);
    return pid;
}
 
char * get_self_executable_directory()
{
    int rval;
    char link_target[1024];
    char *last_slash;
    size_t result_length;
    char *result;
 
    rval =readlink("/proc/self/exe",link_target,sizeof(link_target));
    if(rval == -1)
        abort();
    else
        link_target[rval] = '\0';
 
    last_slash = strrchr(link_target,'/');
    if(last_slash == NULL || last_slash == link_target)
        abort();
 
    result_length = last_slash-link_target;
    result = (char*)malloc(result_length + 1);
    strncpy(result,link_target,result_length);
    result[result_length] = '\0';
    return result;
}
 
unsignedchar *byteArrayToString(unsignedchar *data,int dataLen) {
    char hex_char[] = "0123456789abcdef";
     
    unsignedchar *output = (unsigned char*)malloc(dataLen * 2 + 1);
    bzero(output,dataLen * 2 + 1);
    unsignedchar *ptr = output;
    for(int i = 0; i < dataLen; i++) {
        *ptr++ = hex_char[(data[i] & 0xf0) >> 4];
        *ptr++ = hex_char[(data[i] & 0x0f)];
    }
    return output;
}
 
int main() {
    /*
    printf("/proc/self reports process id %d\n",get_pid_from_proc_self());
    printf("getpid() reports process id %d\n",getpid());
    printf("current program path is %s\n",get_self_executable_directory());
    */
 
    char *msg = (char*)"12345678";
    unsignedchar *buf = (unsigned char *)malloc(128);
    memset(buf,0,128);
    memcpy(buf,msg,strlen(msg));
    char pubPath[MAX_PATH] = {0};
    char priPath[MAX_PATH] = {0};
    char *executePath = get_self_executable_directory();
    sprintf(pubPath,"%s/%s",executePath,PUBSSLKEY);
    sprintf(priPath,"%s/%s",executePath,PRISSLKEY);
 
    printf("rsa pub key path is [%s]\n",pubPath);
    printf("rsa pri key path is [%s]\n",priPath);
 
    unsignedchar *ptr_en = my_encrypt(buf,pubPath,priPath);
    //char *data = char2hex((unsigned char*)ptr_en,strlen(ptr_en));
    char *base64Data = (char*)encode64(ptr_en,128);
    printf("encrypt base64 data is [%s]\n",base64Data);
 
    char *hexData = (char*)byteArrayToString(ptr_en,128);
    printf("encrypt hex data is [%s]\n",hexData);
    return 0;
}

  

2)Android4.2下,使用的加解密代码与之相同,只是编译时需要使用第三方openssl,然后使用ndk-build进行编译,编译成功后,使用如下命令上传到模拟器中:

使用命令 "emulator -avd android4_2"或"emulator-arm -avd android4_2",启动模拟器,我的模拟器是android4_2,如果你的和我不一样,换成你的名称。

使用adb shell登陆模拟器,在data目录下创建文件夹RSATest,将编译成功的可执行文件和rsa_public_key.pem和rsa_private_key.pem上传到该目录

 

3)Java使用的RSA加解密代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
 
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
 
import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
import sun.misc.BASE64Decoder;
 
public class RSAEncrypt {
     
    private static final String DEFAULT_PUBLIC_KEY=
        "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrUUwBjj0lVWubst1p49N9Y9ti" +"\r" +
        "Xh/L4SH5TneNCr1WZHKXDJJM7sLV071UgTl3ENfrnsndNKPXgDDoMBuNnwhCzKHJ" +"\r" +
        "Hu+stxrCWBUKfF/1NawwgBdxz+HIIcwyMVfWGDvc9KSSUXVwTg9frgj9i1FF3TUB" +"\r" +
        "66qVIx3fNOwrjlz+0QIDAQAB" +"\r";
     
    private static final String DEFAULT_PRIVATE_KEY=
        "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOtRTAGOPSVVa5uy" +"\r" +
        "3Wnj031j22JeH8vhIflOd40KvVZkcpcMkkzuwtXTvVSBOXcQ1+ueyd00o9eAMOgw" +"\r" +
        "G42fCELMocke76y3GsJYFQp8X/U1rDCAF3HP4cghzDIxV9YYO9z0pJJRdXBOD1+u" +"\r" +
        "CP2LUUXdNQHrqpUjHd807CuOXP7RAgMBAAECgYBlwRK/vXT9VtGgUxjhOA30s6Bj" +"\r" +
        "CdZv/9sEBgU2LQWwfOD8JgiBUeFYOyYsi3CA5vynO1OI3sFWZ20+icbwV2tnOt4w" +"\r" +
        "A0kevQsnTTgR3RzutqPdMxJT7HseukGCrLcq0FK2UxZwOxFA9ACGQB70YlYk7sbX" +"\r" +
        "p4xYMJXXiz7KIVvuXQJBAPz88QLAkdcxZC/Nmbfvwv/DuyYkZpFmnK5bQUQ26GCU" +"\r" +
        "KIsfeXWdupOCias8ksOHT+XqE0WIGGz6aTA78VcQADsCQQDuHn/NsNpNQ0+lbPcA" +"\r" +
        "2Nd0elCFvS1iIssRu5qAOOqvzyzbhABNGaCGWa+jzz1yoB2Bm0EMhTB8z8z7n/IX" +"\r" +
        "YDhjAkBKw9XWImL3XblmBzTujwTp4UZlt0w4nEKhpIZdSnzSTfbNZrfWco65GVLm" +"\r" +
        "MDiPYGXUZKDdY6MUUczUXGKugCQRAkEAvZAgNFK/Z1TXuh0mAlGeLEcXhXCWCZMj" +"\r" +
        "UImmNL+a7b0ju9m5F6f4KByL+/+GrpMTClPblCkP8bzINeUeKEfcewJBAM6HcCA7" +"\r" +
        "G4Xbg/PeY2338D9IdWdhsRTLBbWBJUGDXXWXumwmZu1Nrqd5sjK111TQilfLTg4G" +"\r" +
        "jb5e2Gx7BcieoS4=" +"\r";
 
    /**
     * 私钥
     */
    private RSAPrivateKey privateKey;
 
    /**
     * 公钥
     */
    private RSAPublicKey publicKey;
     
    /**
     * 字节数据转字符串专用集合
     */
    private static final char[] HEX_CHAR= {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
     
 
    /**
     * 获取私钥
     * @return 当前的私钥对象
     */
    public RSAPrivateKey getPrivateKey() {
        return privateKey;
    }
 
    /**
     * 获取公钥
     * @return 当前的公钥对象
     */
    public RSAPublicKey getPublicKey() {
        return publicKey;
    }
 
    /**
     * 随机生成密钥对
     */
    public void genKeyPair(){
        KeyPairGenerator keyPairGen= null;
        try {
            keyPairGen= KeyPairGenerator.getInstance("RSA");
        }catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        keyPairGen.initialize(1024,new SecureRandom());
        KeyPair keyPair= keyPairGen.generateKeyPair();
        this.privateKey= (RSAPrivateKey) keyPair.getPrivate();
        this.publicKey= (RSAPublicKey) keyPair.getPublic();
    }
 
    /**
     * 从文件中输入流中加载公钥
     * @param in 公钥输入流
     * @throws Exception 加载公钥时产生的异常
     */
    public void loadPublicKey(InputStream in) throws Exception{
        try {
            BufferedReader br= new BufferedReader(new InputStreamReader(in));
            String readLine= null;
            StringBuilder sb= new StringBuilder();
            while((readLine= br.readLine())!=null){
                if(readLine.charAt(0)=='-'){
                    continue;
                }else{
                    sb.append(readLine);
                    sb.append('\r');
                }
            }
            loadPublicKey(sb.toString());
        }catch (IOException e) {
            throw new Exception("公钥数据流读取错误");
        }catch (NullPointerException e) {
            throw new Exception("公钥输入流为空");
        }
    }
 
 
    /**
     * 从字符串中加载公钥
     * @param publicKeyStr 公钥数据字符串
     * @throws Exception 加载公钥时产生的异常
     */
    public void loadPublicKey(String publicKeyStr) throws Exception{
        try {
            BASE64Decoder base64Decoder= new BASE64Decoder();
            byte[] buffer= base64Decoder.decodeBuffer(publicKeyStr);
            KeyFactory keyFactory= KeyFactory.getInstance("RSA");
            X509EncodedKeySpec keySpec= new X509EncodedKeySpec(buffer);
            this.publicKey= (RSAPublicKey) keyFactory.generatePublic(keySpec);
        }catch (NoSuchAlgorithmException e) {
            throw new Exception("无此算法");
        }catch (InvalidKeySpecException e) {
            throw new Exception("公钥非法");
        }catch (IOException e) {
            throw new Exception("公钥数据内容读取错误");
        }catch (NullPointerException e) {
            throw new Exception("公钥数据为空");
        }
    }
 
    /**
     * 从文件中加载私钥
     * @param keyFileName 私钥文件名
     * @return 是否成功
     * @throws Exception
     */
    public void loadPrivateKey(InputStream in) throws Exception{
        try {
            BufferedReader br= new BufferedReader(new InputStreamReader(in));
            String readLine= null;
            StringBuilder sb= new StringBuilder();
            while((readLine= br.readLine())!=null){
                if(readLine.charAt(0)=='-'){
                    continue;
                }else{
                    sb.append(readLine);
                    sb.append('\r');
                }
            }
            loadPrivateKey(sb.toString());
        }catch (IOException e) {
            throw new Exception("私钥数据读取错误");
        }catch (NullPointerException e) {
            throw new Exception("私钥输入流为空");
        }
    }
 
    public void loadPrivateKey(String privateKeyStr) throws Exception{
        try {
            BASE64Decoder base64Decoder= new BASE64Decoder();
            byte[] buffer= base64Decoder.decodeBuffer(privateKeyStr);
            PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer);
            KeyFactory keyFactory= KeyFactory.getInstance("RSA");
            this.privateKey= (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
        }catch (NoSuchAlgorithmException e) {
            throw new Exception("无此算法");
        }catch (InvalidKeySpecException e) {
            throw new Exception("私钥非法");
        }catch (IOException e) {
            throw new Exception("私钥数据内容读取错误");
        }catch (NullPointerException e) {
            throw new Exception("私钥数据为空");
        }
    }
 
    /**
     * 加密过程
     * @param publicKey 公钥
     * @param plainTextData 明文数据
     * @return
     * @throws Exception 加密过程中的异常信息
     */
    public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception{
        if(publicKey==null){
            throw new Exception("加密公钥为空, 请设置");
        }
        Cipher cipher= null;
        try {
//          cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
            cipher= Cipher.getInstance("RSA/ECB/NOPADDING");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] output= cipher.doFinal(plainTextData);
            return output;
        }catch (NoSuchAlgorithmException e) {
            throw new Exception("无此加密算法");
        }catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        }catch (InvalidKeyException e) {
            throw new Exception("加密公钥非法,请检查");
        }catch (IllegalBlockSizeException e) {
            throw new Exception("明文长度非法");
        }catch (BadPaddingException e) {
            throw new Exception("明文数据已损坏");
        }
    }
 
    /**
     * 解密过程
     * @param privateKey 私钥
     * @param cipherData 密文数据
     * @return 明文
     * @throws Exception 解密过程中的异常信息
     */
    public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception{
        if (privateKey==null){
            throw new Exception("解密私钥为空, 请设置");
        }
        Cipher cipher= null;
        try {
//          cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
            cipher= Cipher.getInstance("RSA/ECB/NOPADDING");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] output = cipher.doFinal(cipherData);
//          byte[] output = cipher.doFinal(enBuff);
            return output;
        }catch (NoSuchAlgorithmException e) {
            throw new Exception("无此解密算法");
        }catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        }catch (InvalidKeyException e) {
            throw new Exception("解密私钥非法,请检查");
        }catch (IllegalBlockSizeException e) {
            throw new Exception("密文长度非法");
        }catch (BadPaddingException e) {
            throw new Exception("密文数据已损坏");
        }      
    }
 
     
    /**
     * 字节数据转十六进制字符串
     * @param data 输入数据
     * @return 十六进制内容
     */
    public static String byteArrayToString(byte[] data){
        StringBuilder stringBuilder= new StringBuilder();
        for (int i=0; i<data.length; i++){
            //取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移
            stringBuilder.append(HEX_CHAR[(data[i] & 0xf0)>>>4]);
            //取出字节的低四位 作为索引得到相应的十六进制标识符
            stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
            if (i<data.length-1){
                stringBuilder.append(' ');
            }
        }
        return stringBuilder.toString();
    }
 
    public static void main(String[] args){
        RSAEncrypt rsaEncrypt= new RSAEncrypt();
        //rsaEncrypt.genKeyPair();
 
        String defaultCharsetName = Charset.defaultCharset().displayName();
        System.out.println("defaultCharsetName:"+defaultCharsetName);      
         
        //加载公钥
        try {
            rsaEncrypt.loadPublicKey(RSAEncrypt.DEFAULT_PUBLIC_KEY);
            System.out.println("加载公钥成功");
        }catch (Exception e) {
            System.err.println(e.getMessage());
            System.err.println("加载公钥失败");
        }
 
        //加载私钥
        try {
            rsaEncrypt.loadPrivateKey(RSAEncrypt.DEFAULT_PRIVATE_KEY);
            System.out.println("加载私钥成功");
        }catch (Exception e) {
            System.err.println(e.getMessage());
            System.err.println("加载私钥失败");
        }
 
        //测试字符串
        String encryptStr= "12345678";
         
        try {
            //加密
            byte[] en_content = new byte[128];
            System.arraycopy(encryptStr.getBytes(),0 , en_content, 0, encryptStr.getBytes().length);
            byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(), en_content);
            //解密
            byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), cipher);
            System.out.println("密文长度:"+ cipher.length);
            System.out.println(RSAEncrypt.byteArrayToString(cipher));
            System.out.println("明文长度:"+ plainText.length);
            System.out.println(RSAEncrypt.byteArrayToString(plainText));
            System.out.println(new String(plainText));
        }catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }
}

Java代码中默认公钥和私钥,是之前使用linux命令生成的rsa_public_key.pem和pkcs8_rsa_private_key.pem中的字符串。  

 

需要注意的地方时,我们要加密的字符串是”12345678“,字符长度为为8为,对该字符串进行RSA加解密时,如果使用NOPADDING方式进行填充,它要求的加密长度为128位的倍数,为此,我们在C/C++和Java代码中生成一个128的缓冲区,然后将要加密的字符串拷贝至该缓冲区,之后将该缓冲区最为参数进行加密。

如果你传入的参数不是128位,而是8为,程序可以正常运行,只是不同平台和语言之间得到的加密字符串不一致,不能在多平台和多语言之间使用openssl。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值