转自:http://www.thinkemb.com/wordpress/?p=18

参考:http://blog.csdn.net/shuanyancao/article/details/8985963

http://stackoverflow.com/questions/18152913/aes-aes-cbc-128-aes-cbc-192-aes-cbc-256-encryption-decryption-with-openssl-c

Openssl是很常见的C接口的库,个人觉得易用。以下是AES加密的使用备忘。如果你有一定的密码学基础,那么就很好理解。代码是从网上弄下来的(原始地址已经忘记了),然后在尝试的过程中改了一点东西。其它的cbc、cfb、ecb加密方式的用法都是类似的,只是函数名有点区别,就不一一列举了。

【yasi】IV: Initialization Vector,即初始化向量

一、接口简介

  1. //设置加密密钥,使用字符缓冲区
  2. int AES_set_encrypt_key(
  3. const unsigned char *userKey,
  4. const int bits,
  5. AES_KEY *key);
  6. //设置解密密钥,同样适用字符缓冲区
  7. int AES_set_decrypt_key(
  8. const unsigned char *userKey,
  9. const int bits,
  10. AES_KEY *key);
  11. //加解密的接口,通过最后的enc来区分是加密还是解密操作
  12. //每次执行AES_cbc_encrypt后,iv(向量)会被更新,
  13. //所以需要自己保存它。
  14. void AES_cbc_encrypt(
  15. const unsigned char *in,
  16. unsigned char *out,
  17. const unsigned long length,
  18. const AES_KEY *key,
  19. unsigned char *ivec,
  20. const int enc);

?

二、一个简单的Makefile

【yasi】针对CentOS环境,做了修改

  1. LNK_OPT = -g -L/usr/lib64/ -lssl
  2. all:
  3. rm -f codec
  4. g++ -g aes_codec.cpp -o codec $(LNK_OPT)
  5. clean:
  6. rm -f codec

三、示例代码

【yasi】对源链接的代码做了点修改:随机明码 改 静态明码

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <openssl/aes.h>
  4. #include <openssl/rand.h>
  5. /* file testaes.cpp */
  6. static void hexdump(
  7. FILE *f,
  8. const char *title,
  9. const unsigned char *s,
  10. int l)
  11. {
  12. int n = 0;
  13. fprintf(f, "%s", title);
  14. for (; n < l; ++n) {
  15. if ((n % 16) == 0) {
  16. fprintf(f, "\n%04x", n);
  17. }
  18. fprintf(f, " %02x", s[n]);
  19. }
  20. fprintf(f, "\n");
  21. }
  22. int main(int argc, char **argv)
  23. {
  24. //128bits key.
  25. unsigned char   rkey[16];
  26. //Internal key.
  27. AES_KEY         key;
  28. //Testdata.
  29. // [yasi] Make static content instead of random text
  30. unsigned char   plaintext[AES_BLOCK_SIZE * 4] =
  31. {
  32. 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'i', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'i',
  33. '0', '1', '2', '3', '4', '5', '6', '7', '0', '1', '2', '3', '4', '5', '6', '7',
  34. 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'i', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'i',
  35. '0', '1', '2', '3', '4', '5', '6', '7', '0', '1', '2', '3', '4', '5', '6', '7'
  36. };
  37. unsigned char   ciphertext[AES_BLOCK_SIZE * 4];
  38. unsigned char   checktext[AES_BLOCK_SIZE * 4];
  39. //Init vector.
  40. unsigned char   iv[AES_BLOCK_SIZE * 4];
  41. //Save vector.
  42. unsigned char   saved_iv[AES_BLOCK_SIZE * 4];
  43. int nr_of_bits = 0;
  44. int nr_of_bytes = 0;
  45. //Zeror buffer.
  46. memset(ciphertext, 0, sizeof ciphertext);
  47. memset(checktext, 0, sizeof checktext);
  48. //Generate random
  49. RAND_pseudo_bytes(rkey, sizeof rkey);
  50. RAND_pseudo_bytes(saved_iv, sizeof saved_iv);
  51. hexdump(stdout, "== rkey ==",
  52. rkey,
  53. sizeof(rkey));
  54. hexdump(stdout, "== iv ==",
  55. saved_iv,
  56. sizeof(saved_iv));
  57. printf("\n");
  58. hexdump(stdout, "== plaintext ==",
  59. plaintext,
  60. sizeof(plaintext));
  61. printf("\n");
  62. //Entrypt
  63. memcpy(iv, saved_iv, sizeof(iv));
  64. nr_of_bits = 8 * sizeof(rkey);
  65. AES_set_encrypt_key(rkey, nr_of_bits, &key);
  66. nr_of_bytes = sizeof(plaintext);
  67. AES_cbc_encrypt(plaintext,
  68. ciphertext,
  69. nr_of_bytes,
  70. &key,
  71. iv,
  72. AES_ENCRYPT);
  73. hexdump(stdout, "== ciphertext ==",
  74. ciphertext,
  75. sizeof(ciphertext));
  76. printf("\n");
  77. // [yasi] iv is changed in encryption
  78. hexdump(stdout, "== iv changed ==",
  79. iv,
  80. sizeof(iv));
  81. printf("\n");
  82. //Decrypt
  83. memcpy(iv, saved_iv, sizeof(iv));       // [yasi] without this line, decrypt will fail because iv is changed in encryption
  84. nr_of_bits = 8 * sizeof(rkey);
  85. AES_set_decrypt_key(rkey, nr_of_bits, &key);
  86. nr_of_bytes = sizeof(ciphertext);
  87. AES_cbc_encrypt(ciphertext,
  88. checktext,
  89. nr_of_bytes,
  90. &key, iv,
  91. AES_DECRYPT);
  92. hexdump(stdout, "== checktext ==",
  93. checktext,
  94. sizeof(checktext));
  95. printf("\n");
  96. return 0;
  97. }
 

【yasi 运行结果】

  1. [root@ampcommons02 aes-codec]# ./codec
  2. == rkey ==
  3. 0000 81 ac 9b 38 1c 02 c5 c8 1d 7c a0 3f 87 be f2 c6
  4. == iv ==
  5. 0000 34 a2 f1 f5 f3 93 76 32 cd 77 ad fb c8 82 f2 1b
  6. 0010 f3 cc 51 f6 35 f3 49 8d 44 97 8c 2c 89 50 0d d7
  7. 0020 68 21 d7 2f 0a 90 29 c1 dd c9 39 bc 7c 4f 18 2f
  8. 0030 04 cc 42 5e 84 8e fe a9 c5 49 00 9f 30 55 94 c0
  9. == plaintext ==
  10. 0000 61 62 63 64 65 66 67 69 61 62 63 64 65 66 67 69
  11. 0010 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37
  12. 0020 61 62 63 64 65 66 67 69 61 62 63 64 65 66 67 69
  13. 0030 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37
  14. == ciphertext ==
  15. 0000 c4 63 72 29 21 28 7b a2 27 24 4a e4 bb 95 1a d1
  16. 0010 b8 13 0e 77 0c 8a a4 09 2f ca 85 43 41 b5 5b d5
  17. 0020 a3 60 92 58 5b dd 45 0c e2 62 af f9 43 81 d7 06
  18. 0030 41 8e 85 28 3e eb 72 b5 ee 84 8c 27 7e 67 20 f6
  19. == iv changed ==
  20. 0000 41 8e 85 28 3e eb 72 b5 ee 84 8c 27 7e 67 20 f6
  21. 0010 f3 cc 51 f6 35 f3 49 8d 44 97 8c 2c 89 50 0d d7
  22. 0020 68 21 d7 2f 0a 90 29 c1 dd c9 39 bc 7c 4f 18 2f
  23. 0030 04 cc 42 5e 84 8e fe a9 c5 49 00 9f 30 55 94 c0
  24. == checktext ==
  25. 0000 61 62 63 64 65 66 67 69 61 62 63 64 65 66 67 69
  26. 0010 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37
  27. 0020 61 62 63 64 65 66 67 69 61 62 63 64 65 66 67 69
  28. 0030 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37

可见,encryption之后,IV立即被修改了。所以,为了能正确decrypt,在decrypt时,必须使用先前encrypt时的IV,即代码第98行。

 
【第二次运行的结果】
  1. [root@ampcommons02 aes-codec]# ./codec
  2. == rkey ==
  3. 0000 29 68 75 4d a5 9e 83 9a ed f8 ec bc 2e b8 09 7e
  4. == iv ==
  5. 0000 b8 21 09 de 8f 58 6e be 73 be a7 10 fb 91 87 65
  6. 0010 65 9c d7 0e 4c 88 d2 65 ae de 0b 49 40 c7 75 df
  7. 0020 19 69 53 0b 11 5d ac e7 08 f6 ae df 16 66 e0 13
  8. 0030 75 41 f7 bb be 56 a1 dd a7 3e fb 4e 5d 9e e4 a2
  9. == plaintext ==
  10. 0000 61 62 63 64 65 66 67 69 61 62 63 64 65 66 67 69
  11. 0010 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37
  12. 0020 61 62 63 64 65 66 67 69 61 62 63 64 65 66 67 69
  13. 0030 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37
  14. == ciphertext ==
  15. 0000 5e 85 9c e8 65 d6 3b f9 03 9a a0 b5 78 bd f6 d4
  16. 0010 11 70 94 c1 c3 78 9a 1d 12 9a 84 48 3a 70 88 13
  17. 0020 d6 b5 bf c6 e8 e1 76 dc 3c b9 b0 4e b9 bb c4 74
  18. 0030 35 3d ac fc 29 e3 a0 64 d7 76 ab 76 c7 af dd 39
  19. == iv changed ==
  20. 0000 35 3d ac fc 29 e3 a0 64 d7 76 ab 76 c7 af dd 39
  21. 0010 65 9c d7 0e 4c 88 d2 65 ae de 0b 49 40 c7 75 df
  22. 0020 19 69 53 0b 11 5d ac e7 08 f6 ae df 16 66 e0 13
  23. 0030 75 41 f7 bb be 56 a1 dd a7 3e fb 4e 5d 9e e4 a2
  24. == checktext ==
  25. 0000 61 62 63 64 65 66 67 69 61 62 63 64 65 66 67 69
  26. 0010 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37
  27. 0020 61 62 63 64 65 66 67 69 61 62 63 64 65 66 67 69
  28. 0030 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37

可见,两次运行,虽然encrypt的明码是一样的,但encrypt出来的结果是不同的。随机明码 改 静态明码 的目的就是为了比较两次encrypt的结果。即,相同的明码用不同的IV做encrypt,结果是不同的。

 
【屏蔽第98行重新编译后的执行结果】
  1. [root@ampcommons02 aes-codec]# ./codec
  2. == rkey ==
  3. 0000 69 ef eb 49 25 5a c2 5e 0d 77 8a cb e6 fe ad 1d
  4. == iv ==
  5. 0000 8e 05 8c 50 2f 69 9d fb 64 3e cd e6 2d 38 26 1c
  6. 0010 6e 21 00 e6 32 3f c6 ca 93 8b c1 e3 47 9a bd 81
  7. 0020 d7 e5 0b 63 dc f8 9d 1f 13 49 35 25 70 4e 64 c2
  8. 0030 ea 0c d0 78 e7 6c 65 64 41 4d db 2b 50 4d b4 06
  9. == plaintext ==
  10. 0000 61 62 63 64 65 66 67 69 61 62 63 64 65 66 67 69
  11. 0010 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37
  12. 0020 61 62 63 64 65 66 67 69 61 62 63 64 65 66 67 69
  13. 0030 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37
  14. == ciphertext ==
  15. 0000 a4 ed ba 4b 9f e9 74 bd 6d f6 03 76 79 9f 17 4f
  16. 0010 0c cd f3 b8 da 69 44 81 c9 f2 8b 03 83 0d 9d 77
  17. 0020 12 48 ea 46 3f eb 58 fd 48 c5 cc 2d 74 6c 99 4f
  18. 0030 93 bd 0d 06 f3 55 40 11 cb e7 d4 29 3b 8f 15 76
  19. == iv changed ==
  20. 0000 93 bd 0d 06 f3 55 40 11 cb e7 d4 29 3b 8f 15 76
  21. 0010 6e 21 00 e6 32 3f c6 ca 93 8b c1 e3 47 9a bd 81
  22. 0020 d7 e5 0b 63 dc f8 9d 1f 13 49 35 25 70 4e 64 c2
  23. 0030 ea 0c d0 78 e7 6c 65 64 41 4d db 2b 50 4d b4 06
  24. == checktext ==
  25. 0000 7c da e2 32 b9 5a ba 83 ce bb 7a ab 73 d1 54 03
  26. 0010 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37
  27. 0020 61 62 63 64 65 66 67 69 61 62 63 64 65 66 67 69
  28. 0030 30 31 32 33 34 35 36 37 30 31 32 33 34 35 36 37

可见,decrypt时使用和encrypt时不同的IV,不能正确decrypt出先前的明码。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
【yasi】Openssl官方wiki,《EVP Symmetric Encryption and Decryption》中,有个的简单例子,整理如下(Linux下运行):(代码下载)
algo_aes.h
  1. #ifndef ALGO_AES_H
  2. #define ALGO_AES_H
  3. int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
  4. unsigned char *iv, unsigned char *ciphertext);
  5. int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
  6. unsigned char *iv, unsigned char *plaintext);
  7. #endif

algo_aes.c

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include "algo_aes.h"
  4. #include <openssl/evp.h>
  5. void handleErrors(void)
  6. {
  7. ERR_print_errors_fp(stderr);
  8. abort();
  9. }
  10. int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
  11. unsigned char *iv, unsigned char *ciphertext)
  12. {
  13. EVP_CIPHER_CTX *ctx;
  14. int len;
  15. int ciphertext_len;
  16. /* Create and initialise the context */
  17. if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
  18. /* Initialise the encryption operation. IMPORTANT - ensure you use a key
  19. * and IV size appropriate for your cipher
  20. * In this example we are using 256 bit AES (i.e. a 256 bit key). The
  21. * IV size for *most* modes is the same as the block size. For AES this
  22. * is 128 bits */
  23. if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
  24. handleErrors();
  25. /* Provide the message to be encrypted, and obtain the encrypted output.
  26. * EVP_EncryptUpdate can be called multiple times if necessary
  27. */
  28. if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
  29. handleErrors();
  30. ciphertext_len = len;
  31. /* Finalise the encryption. Further ciphertext bytes may be written at
  32. * this stage.
  33. */
  34. if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
  35. ciphertext_len += len;
  36. /* Clean up */
  37. EVP_CIPHER_CTX_free(ctx);
  38. return ciphertext_len;
  39. }
  40. int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
  41. unsigned char *iv, unsigned char *plaintext)
  42. {
  43. EVP_CIPHER_CTX *ctx;
  44. int len;
  45. int plaintext_len;
  46. /* Create and initialise the context */
  47. if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
  48. /* Initialise the decryption operation. IMPORTANT - ensure you use a key
  49. * and IV size appropriate for your cipher
  50. * In this example we are using 256 bit AES (i.e. a 256 bit key). The
  51. * IV size for *most* modes is the same as the block size. For AES this
  52. * is 128 bits */
  53. if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv))
  54. handleErrors();
  55. /* Provide the message to be decrypted, and obtain the plaintext output.
  56. * EVP_DecryptUpdate can be called multiple times if necessary
  57. */
  58. if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
  59. handleErrors();
  60. plaintext_len = len;
  61. /* Finalise the decryption. Further plaintext bytes may be written at
  62. * this stage.
  63. */
  64. if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
  65. plaintext_len += len;
  66. /* Clean up */
  67. EVP_CIPHER_CTX_free(ctx);
  68. return plaintext_len;
  69. }

main.c

  1. #include "algo_aes.h"
  2. #include <stdio.h>
  3. #include <string.h>
  4. //#include <openssl/evp.h>
  5. int main(int arc, char *argv[])
  6. {
  7. /* Set up the key and iv. Do I need to say to not hard code these in a
  8. * real application? :-)
  9. */
  10. /* A 256 bit key */
  11. unsigned char *key = "01234567890123456789012345678901";
  12. /* A 128 bit IV */
  13. unsigned char *iv = "01234567890123456";
  14. /* Message to be encrypted */
  15. unsigned char *plaintext =
  16. "The quick brown fox jumps over the lazy dog1234";
  17. /* Buffer for ciphertext. Ensure the buffer is long enough for the
  18. * ciphertext which may be longer than the plaintext, dependant on the
  19. * algorithm and mode
  20. */
  21. unsigned char ciphertext[64];
  22. /* Buffer for the decrypted text */
  23. unsigned char decryptedtext[64];
  24. int decryptedtext_len, ciphertext_len;
  25. /* Initialise the library */
  26. /*  ERR_load_crypto_strings();
  27. OpenSSL_add_all_algorithms();
  28. OPENSSL_config(NULL);*/
  29. printf("Plaintext is:\n%s~\n", plaintext);
  30. /* Encrypt the plaintext */
  31. ciphertext_len = encrypt(plaintext, strlen(plaintext), key, iv,
  32. ciphertext);
  33. /* Do something useful with the ciphertext here */
  34. printf("Ciphertext is %d bytes long:\n", ciphertext_len);
  35. BIO_dump_fp(stdout, ciphertext, ciphertext_len);
  36. /* Decrypt the ciphertext */
  37. decryptedtext_len = decrypt(ciphertext, ciphertext_len, key, iv,
  38. decryptedtext);
  39. /* Add a NULL terminator. We are expecting printable text */
  40. decryptedtext[decryptedtext_len] = '\0';
  41. /* Show the decrypted text */
  42. printf("Decrypted text is:\n");
  43. printf("%s~\n", decryptedtext);
  44. /* Clean up */
  45. EVP_cleanup();
  46. ERR_free_strings();
  47. return 0;
  48. }

Mekefile:

  1. OBJ_DIR = ./obj
  2. BIN_DIR = ./bin
  3. SRC_DIR = ./
  4. OBJS = \
  5. $(OBJ_DIR)/algo_aes.o \
  6. $(OBJ_DIR)/main.o
  7. TARGET = $(BIN_DIR)/main
  8. INC_OPT = -I./
  9. LNK_OPT = -lssl
  10. $(TARGET) : clean chkobjdir chkbindir $(OBJS)
  11. gcc -g -o $@ $(OBJS) $(LNK_OPT)
  12. $(OBJ_DIR)/%.o : $(SRC_DIR)/%.c
  13. gcc -g $(INC_OPT) -c -o $@ $<
  14. chkobjdir :
  15. @if test ! -d $(OBJ_DIR) ; \
  16. then \
  17. mkdir $(OBJ_DIR) ; \
  18. fi
  19. chkbindir :
  20. @if test ! -d $(BIN_DIR) ; \
  21. then \
  22. mkdir $(BIN_DIR) ; \
  23. fi
  24. clean :
  25. -rm -f $(TARGET)
  26. -rm -rf $(OBJ_DIR)
运行结果:
  1. Plaintext is:
  2. The quick brown fox jumps over the lazy dog1234~
  3. Ciphertext is 48 bytes long:
  4. 0000 - e0 6f 63 a7 11 e8 b7 aa-9f 94 40 10 7d 46 80 a1   .oc.......@.}F..
  5. 0010 - 17 99 43 80 ea 31 d2 a2-99 b9 53 02 d4 39 b9 70   ..C..1....S..9.p
  6. 0020 - e9 29 d5 a8 03 bd 71 31-b8 c3 6f 3d 39 3a 3d 3d   .)....q1..o=9:==
  7. Decrypted text is:
  8. The quick brown fox jumps over the lazy dog1234~

注意:参考

AES算法的块(block)的长度固定为16字节。假设一个字符串在AES加密前的长度为cleanLen,加密后的长度为cipherLen,则二者有下面的关系,其中的“/”是整除。

cipherLen = (clearLen/16 + 1) * 16

比如:(注意第二行,即使48刚好能被16整除,也要额外追加一个16字节的块)
clearLen cipherLen 
47 48
48 64
49 64
可见,对于AES算法:
1)加密后的长度>=加密前的长度
2)解密后的长度<=解密前的长度
这对于写代码时的指导意义在于:
1)假如我们要做AES加密的字符串为“The quick brown fox jumps over the lazy dog”,它的长度(不带/0)为43字节,则我们可以计算出加密后的串的长度为 (43 / 16 + 1) * 16 = 48 字节,于是就可以申明加密后的数组如下
unsigned char ciphertextp[48];
2)假如我们知道AES加密后的串的长度为64字节,那么就可以申明解密后的数组如下
unsigned char decryptedtext[64];

[转]使用Openssl的AES加密算法的更多相关文章

  1. 使用Openssl的AES加密算法

    原文链接: http://blog.csdn.net/yasi_xi/article/details/13997337 Openssl是很常见的C接口的库,个人觉得易用.以下是AES加密的使用备忘.如 ...

  2. openssl之aes加密(源码分析 AES_encrypt 与 AES_cbc_encrypt ,加密模式)

    首先要了解AES加密是什么,以及几种加密模式的区别.之后才是编程.具体的编程案例,在下面的链接. openssl之aes加密(AES_cbc_encrypt 与 AES_encrypt 的编程案例) ...

  3. php RSA和AES加密算法

    一.RSA加密 RSA只说PHP中的应用,详细的算法原理解释,请自行百度,或者参考(RSA加密算法-详细解释以及公钥加密为什么每次都不一样) 总结:公钥加密.私钥解密.私钥签名.公钥验签. 注意: 1 ...

  4. AES加密算法C++实现

    我从网上下载了一套AES加密算法的C++实现,代码如下: (1)aes.h #ifndef SRC_UTILS_AES_H #define SRC_UTILS_AES_H class AES { pu ...

  5. PHP android ios相互兼容的AES加密算法

    APP项目用户密码传输一直没有用HTTPS,考虑到用户的隐私暂时先用AES对密码加密,以后也可以用于手机端与服务端加密交互. PHP的免费版phpAES项目,手机端解码各种不对. 好不容易找了PHP ...

  6. Qt使用AES加密算法对字符串进行加密

          因工作需要,需要对字符串进行加密处理,在网上找了很长时间,终于找到了一个可以使用的aes加密算法.其源代码采用c++编写而成,但其头文件引用windows.h,经过修改部分代码,将#inc ...

  7. Android AES加密算法及事实上现

    昨天老大叫我看看android加密算法.于是网上找了找,找到了AES加密算法.(当然还有MD5,BASE64什么的http://snowolf.iteye.com/blog/379860这篇文章列举了 ...

  8. iOS,Android,.NET通用AES加密算法

    原文:iOS,Android,.NET通用AES加密算法 这两天为移动App开发API,结果实现加密验证时碰到一大坑.这里不得不吐槽下又臭又硬的iOS,Windows Server无法解密出正确的结果 ...

  9. Android AES加密算法,现在实际上

    昨天,老板让我来看看android加密算法.于是在网上找了找,发现AES加密算法.(当然,MD5,BASE64什么http://snowolf.iteye.com/blog/379860这篇文章列举了 ...

随机推荐

  1. OSG+Python

    测试平台(1)Fedora19 x86 [cc@localhost ~]$ lspci | grep VGA :) :00.0 VGA compatible controller: NVIDIA Co ...

  2. Arch最小化安装X

    Xorg xorg-server 安装xorg-server pacman -S xorg-server 可选:xorg-server-utils pacman -S xorg-server-util ...

  3. $each $position $sort $slice

    $push 向数组中添加元素 $each 循环数据(循环添加数据到数组) $sort 对数组进行排序(1:升序:-1:降序.) $slice 对整个collection表进行数据裁减,用的时候一定要当 ...

  4. Hanoi汉诺塔问题——递归与函数自调用算法

    题目描述 Description 有N个圆盘,依半径大小(半径都不同),自下而上套在A柱上,每次只允许移动最上面一个盘子到另外的柱子上去(除A柱外,还有B柱和C柱,开始时这两个柱子上无盘子),但绝不允 ...

  5. Openjudge-计算概论(A)-找和为K的两个元素

    描述: 在一个长度为n(n < 1000)的整数序列中,判断是否存在某两个元素之和为k. 输入第一行输入序列的长度n和k,用空格分开.第二行输入序列中的n个整数,用空格分开.输出如果存在某两个元 ...

  6. 网页 JavaScript的DOM操作

    今天,我首先对之前学习的内容进行了复习,然后学习了当鼠标指向某一个按钮时,切换对应的背景图片. <div id="d1"> </div> <input ...

  7. 一个神奇SQL引发的故障【转】

    前几天一个客户数据库主实例告警,诊断过程中发现是由一个慢SQL导致的数据库故障,而在排查逐步深入之后却发现这个现象的不可思议. 问题描述 2016年12日09日,大概9点26分左右,一个客户的生产库主 ...

  8. 启动tomcat时报错:java.lang.OutOfMemoryError: PermGen space

    1.修改myeclipse.ini 在Myeclipse安装目录下G:\MyEclipse8.5\Genuitec\MyEclipse 8.5有一个myeclipse.ini配置文件,设置如下: -v ...

  9. python 实现excel转化成json文件

    1.准备工作 python 2.7 安装 安装xlrd -- pip install xlrd 2. 直接上代码 import xlrd from collections import Ordered ...

  10. HDU2544-最短路(最短路模版题目)

    Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要 ...