AES(Advanced Encryption Standard)是一种对称加密算法,它是目前广泛使用的加密算法之一。AES算法是由美国国家标准与技术研究院(NIST)于2001年发布的,它取代了原先的DES(Data Encryption Standard)算法,成为新的标准。AES是一种对称加密算法,意味着加密和解密使用相同的密钥。这就要求密钥的安全性非常重要,因为任何拥有密钥的人都能进行加密和解密操作。其密钥长度,包括128位、192位和256位。不同长度的密钥提供了不同级别的安全性,通常更长的密钥长度意味着更高的安全性。

该算法支持多种工作模式,其中两种常见的模式是CBC(Cipher Block Chaining)和ECB(Electronic Codebook)。

  1. CBC 模式(Cipher Block Chaining):

    • 工作原理:

      • CBC模式对每个明文块进行加密前,先与前一个密文块进行异或操作。首个块使用一个初始化向量(IV)与明文异或。这种链式反馈机制使得每个密文块的加密都依赖于前一个块的密文,从而增加了安全性。
    • 特点:
      • 带有初始化向量,对同样的明文块加密得到的密文块会随着其前面的明文块的不同而不同。
      • 适用于加密长度超过一个块的数据。
    • 优点和缺点:
      • 优点:提供更高的安全性,适用于加密大块的数据。
      • 缺点:由于加密是依赖于前一个块的密文,所以无法进行并行加密处理。
  2. ECB 模式(Electronic Codebook):
    • 工作原理:

      • ECB模式将明文分割成块,每个块独立加密,然后再组合成密文。相同的明文块将始终加密为相同的密文块。
    • 特点:
      • 不需要初始化向量,同样的明文会得到同样的密文。
      • 适用于加密独立的数据块,但对于相同的块,ECB模式下的输出相同。
    • 优点和缺点:
      • 优点:简单,易于实现。
      • 缺点:相同的明文块生成相同的密文块,可能导致安全性问题。不适用于加密大块的数据。

在选择模式时,需要根据具体的应用场景和需求权衡安全性和性能。一般来说,CBC模式是更安全的选择,而ECB模式可能更容易实现和理解。在实际应用中,还可以考虑其他模式,如CTR(Counter)模式和GCM(Galois/Counter Mode)模式等,这些模式结合了安全性和性能的考虑。

本次案例中所需要使用的头文件信息如下所示;

#define  _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <openssl/err.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/crypto.h>
#include <openssl/pem.h> extern "C"
{
#include <openssl/applink.c>
} #pragma comment(lib,"libssl_static.lib")
#pragma comment(lib,"libcrypto.lib")

使用CBC模式加解密

Cipher Block Chaining (CBC) 模式是一种对称加密的分组密码工作模式。在 CBC 模式中,明文被分成固定大小的块,并使用加密算法逐个处理这些块。每个块都与前一个块的密文进行异或运算,然后再进行加密。这个过程导致了一种“链接”效果,因此得名 Cipher Block Chaining。

以下是 CBC 模式的详细概述:

初始向量 (Initialization Vector, IV)

  • 在 CBC 模式中,每个消息的第一个块使用一个初始向量 (IV)。IV 是一个固定长度的随机数,它在每次加密不同消息时都应该是唯一的。IV 的作用是在每个块的加密中引入随机性,以防止相同的明文块生成相同的密文块。

分组加密

  • 消息被分成固定大小的块(通常为 64 比特或 128 比特),然后每个块都被分组加密。最常用的块加密算法是 AES。

异或运算

  • 在每个块加密之前,明文块与前一个密文块进行异或运算。这就是“链接”发生的地方。第一个块与 IV 异或。

加密

  • 异或运算后的结果被送入块加密算法进行加密。得到的密文块成为下一个块的 IV。

解密

  • 在解密时,密文块被送入块解密算法进行解密。解密后的结果与前一个密文块进行异或运算,得到明文块。

模式串行化

  • CBC 模式是串行的,因为每个块的加密都依赖于前一个块的密文。这也意味着无法并行处理整个消息。

填充

  • 如果明文的长度不是块大小的整数倍,需要进行填充。常见的填充方案有 PKCS#7 填充。

安全性

  • 当使用 CBC 模式时,密文块的顺序对安全性至关重要。如果消息的两个块对调,解密后会得到不同的明文。因此,必须保证密文块的顺序不被篡改。

使用场景

  • CBC 模式常用于保护传输层安全协议(如 TLS)中,以提供加密和数据完整性。

总体而言,CBC 模式提供了一种相对强大的加密方法,但在实现时需要注意使用随机且不可预测的 IV 以及处理填充的问题。

AES_set_encrypt_key 函数。具体来说,它用于将原始密钥设置为可以在 AES 加密算法中使用的格式。以下是该函数的原型:

int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
  • userKey:指向用于设置密钥的输入数据的指针,即原始密钥。
  • bits:密钥长度,以比特为单位。在使用 AES 加密算法时,通常为 128、192 或 256。
  • key:指向 AES_KEY 结构的指针,用于存储设置后的密钥信息。

该函数返回值为零表示成功,非零表示失败。成功调用后,key 参数中存储了经过格式化的密钥信息,可以在后续的 AES 加密操作中使用。

AES_cbc_encrypt 是 OpenSSL 库中用于执行 AES 算法中的 Cipher Block Chaining (CBC) 模式的函数。在 CBC 模式中,每个明文块在加密之前会与前一个密文块进行异或运算,以增加密码的随机性。

以下是 AES_cbc_encrypt 函数的原型:

void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, const int enc);
  • in:指向输入数据(明文)的指针。
  • out:指向输出数据(密文)的指针。
  • length:数据的长度,以字节为单位。
  • key:指向 AES_KEY 结构的指针,其中包含了加密密钥。
  • ivec:Initialization Vector(IV),用于增强密码的随机性,也是前一个密文块。在 CBC 模式中,IV 对于第一个数据块是必需的,之后的 IV 由前一个密文块决定。
  • enc:指定操作是加密(AES_ENCRYPT)还是解密(AES_DECRYPT)。

AES_set_decrypt_key 函数。该函数用于将加密时使用的密钥调整为解密时使用的密钥,以便进行解密操作。

以下是 AES_set_decrypt_key 函数的原型:

int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
  • userKey:指向用于设置解密密钥的输入密钥数据的指针。
  • bits:密钥长度,以比特为单位。支持的长度包括 128、192 和 256 比特。
  • key:指向 AES_KEY 结构的指针,该结构将存储设置后的解密密钥。

实现加解密功能,如下openssl_aes_cbc_encrypt用于使用CBC模式加密数据,openssl_aes_cbc_decrypt则相反用于解密数据。

// 初始化密钥
const unsigned char key[AES_BLOCK_SIZE] = { 0x12,0x55,0x64,0x69,0xf1 }; // 初始化向量
unsigned char iv[AES_BLOCK_SIZE] = { 0 }; // AES CBC 模式加密
// 参数:
// - in: 待加密的数据
// - len: 待加密数据的长度
// - out: 存放加密结果的缓冲区
// 返回值:
// - 返回填充后加密数据的长度,失败返回-1
int openssl_aes_cbc_encrypt(char* in, size_t len, char* out)
{
AES_KEY aes; // 填充数据为AES_BLOCK_SIZE的整数倍
char* aesIn;
int blockNum, aesInLen; // 设置加密密钥
if (AES_set_encrypt_key(key, 128, &aes) < 0)
{
return -1;
} // 判断原始数据长度是否AES_BLOCK_SIZE的整数倍
if ((len % AES_BLOCK_SIZE) != 0)
{
// 不是整数倍则用0填充
blockNum = len / AES_BLOCK_SIZE + 1;
aesInLen = blockNum * AES_BLOCK_SIZE;
aesIn = (char*)calloc(aesInLen, 1);
memcpy(aesIn, in, len);
}
else
{
aesInLen = len;
aesIn = (char*)calloc(aesInLen, 1);
memcpy(aesIn, in, len);
} // AES CBC 模式加密
AES_cbc_encrypt((unsigned char*)aesIn, (unsigned char*)out, aesInLen, &aes, iv, AES_ENCRYPT); // 释放分配的内存
free(aesIn); // 返回填充后加密数据的长度
return aesInLen;
} // AES CBC 模式解密
// 参数:
// - in: 待解密的数据
// - len: 待解密数据的长度
// - out: 存放解密结果的缓冲区
// 返回值:
// - 成功返回0,失败返回-1
int openssl_aes_cbc_decrypt(char* in, size_t len, char* out)
{
AES_KEY aes; // 设置解密密钥
if (AES_set_decrypt_key(key, 128, &aes) < 0)
{
return -1;
} // AES CBC 模式解密
AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &aes, iv, AES_DECRYPT); // 返回成功
return 0;
}

当需要对数据加密时,首先打开被加密文件这里我们打开的时csdn.zip文件,加密后会写出为csdn.cbc文件;

int main(int argc, char* argv[])
{
// 存放填充字节数的数组
char offset[4] = { '0' }; char* src = nullptr, *dst = nullptr;
int inlen, outlen, size;
FILE* srcFile, *dstFile; // 打开被加密源文件
srcFile = fopen("d://comp/csdn.zip", "rb"); // 加密后写出文件
dstFile = fopen("d://comp/csdn.cbc", "wb+"); // 获取文件大小
fseek(srcFile, 0, SEEK_END);
inlen = ftell(srcFile);
if (inlen < 0)
{
return 0;
}
fseek(srcFile, 0, SEEK_SET); // -------------------------------------------------------
// 开始加密
src = (char*)calloc(inlen, 1);
size = fread(src, 1, inlen, srcFile);
std::cout << "读入字节: " << size << std::endl; // 输出变量申请的空间额外增加16字节
outlen = (inlen / 16 + 1) * 16;
dst = (char*)calloc(outlen, 1); // 调用加密函数
size = openssl_aes_cbc_encrypt(src, inlen, dst); // 获取填充的字节数,记录到输出文件的前4个字节内
sprintf(offset, "%d", size - inlen);
fwrite(offset, sizeof(char), 4, dstFile); // -------------------------------------------------------
// 输出加密后的文件或者解密后的文件,文件大小应与原始文件一致
size = fwrite(dst, 1, size, dstFile);
std::cout << "输出文件大小: " << size << std::endl; fcloseall();
free(src);
free(dst);
system("pause");
return 0;
}

运行后输出效果图如下所示;

解密时同样需要打开文件,将加密文件csdn.cbc打开,并解密输出成csdnde.zip文件;

int main(int argc, char* argv[])
{
// 存放填充字节数的数组
char offset[4] = { '0' }; char* src = nullptr, *dst = nullptr;
int inlen, outlen, size;
FILE* srcFile, *dstFile; // 打开加密后的文件
srcFile = fopen("d://comp/csdn.cbc", "rb"); // 解密后写出的文件
dstFile = fopen("d://comp/csdnde.zip", "wb+"); // 获取文件大小
fseek(srcFile, 0, SEEK_END);
inlen = ftell(srcFile);
if (inlen < 0)
{
return 0;
}
fseek(srcFile, 0, SEEK_SET); // -------------------------------------------------------
fread(offset, sizeof(char), 4, srcFile);
inlen -= 4;
src = (char*)calloc(inlen, 1); // 从加密后的文件中获取填充的字节数
size = fread(src, 1, inlen, srcFile);
std::cout << "读入字节: " << size << std::endl; // 得到原始文件的大小
size = size - atoi(offset); outlen = (inlen / 16 + 1) * 16;
dst = (char*)calloc(outlen, 1); // 解密
openssl_aes_cbc_decrypt(src, inlen, dst); // ------------------------------------------------------- // 输出加密后的文件或者解密后的文件,文件大小应与原始文件一致
size = fwrite(dst, 1, size, dstFile);
std::cout << "输出文件大小: " << size << std::endl; fcloseall();
free(src);
free(dst);
system("pause");
return 0;
}

运行后输出效果图如下所示;

使用ECB模式加解密

Electronic Codebook (ECB) 模式是一种对称加密的分组密码工作模式。在 ECB 模式中,每个明文块都被独立加密,不受其他块的影响。这意味着相同的明文块将始终生成相同的密文块,这可能导致一些安全性问题。

以下是 ECB 模式的详细概述:

分组加密

  • 消息被分成固定大小的块(通常为 64 比特或 128 比特),然后每个块都被独立加密。最常用的块加密算法是 AES。

无链接

  • 在 ECB 模式中,每个块的加密是独立的,不会受到前一个或后一个块的影响。这意味着相同的明文块将生成相同的密文块。

模式串行化

  • ECB 模式允许对整个消息进行并行处理,因为每个块都是独立加密的。这是与 CBC 模式相比的一个优势,因为它允许更高效的实现。

填充

  • 如果明文的长度不是块大小的整数倍,需要进行填充。常见的填充方案有 PKCS#7 填充。

安全性问题

  • 主要的安全性问题在于相同的明文块生成相同的密文块,这可能导致一些攻击。例如,如果两个块的内容相同,那么它们的密文也将相同。

使用场景

  • 由于安全性问题,ECB 模式并不适合所有场景。一般来说,ECB 模式主要用于对称加密算法的基本理解和学术研究,而在实际应用中更常使用其他工作模式,如 CBC 或 GCM。

总体而言,ECB 模式是一种简单的分组密码工作模式,但由于安全性问题,实际应用中更常使用其他工作模式。

AES_ecb_encrypt 是 OpenSSL 库中用于执行 AES 算法的 ECB 模式加密的函数。下面是对该函数的详细概述:

int AES_ecb_encrypt(const unsigned char *input, unsigned char *output, const AES_KEY *key, const int enc);

参数说明:

  • input: 要加密的数据的输入缓冲区的指针。
  • output: 加密后的数据的输出缓冲区的指针。
  • key: AES 密钥的结构体指针,其中包含了加密所需的密钥信息。
  • enc: 一个整数值,用于指定是执行加密(AES_ENCRYPT)还是解密(AES_DECRYPT)操作。

返回值:

  • 返回 0 表示成功,其他值表示错误。

功能说明:

  • AES_ecb_encrypt 函数用于在 ECB 模式下执行 AES 算法的加密或解密操作,具体取决于 enc 参数。
  • 在 ECB 模式下,该函数将输入的数据块独立地加密(或解密),每个块的输出结果不受前后块的影响。
  • 函数通过 key 参数提供的密钥信息执行加密或解密操作。

AES_ecb_encrypt 是 OpenSSL 库中用于执行 AES 算法的 ECB 模式加密或解密的函数。下面是对该函数的详细概述:

int AES_ecb_encrypt(const unsigned char *input, unsigned char *output, const AES_KEY *key, const int enc);

参数说明:

  • input: 要加密或解密的数据块的输入缓冲区指针。
  • output: 加密或解密后的数据块的输出缓冲区指针。
  • key: AES 密钥的结构体指针,包含了加密或解密所需的密钥信息。
  • enc: 一个整数值,用于指定是执行加密(AES_ENCRYPT)还是解密(AES_DECRYPT)操作。

返回值:

  • 返回 0 表示成功,其他值表示错误。

功能说明:

  • AES_ecb_encrypt 函数用于在 ECB 模式下执行 AES 算法的加密或解密操作,具体取决于 enc 参数。
  • 在 ECB 模式下,该函数将输入的数据块独立地加密(或解密),每个块的输出结果不受前后块的影响。
  • 函数通过 key 参数提供的密钥信息执行加密或解密操作。
// AES ECB 模式加密
// 参数:
// - in: 待加密的数据
// - len: 待加密数据的长度
// - out: 存放加密结果的缓冲区
// 返回值:
// - 成功返回填充后加密数据的长度,失败返回-1
int openssl_aes_ecb_enrypt(char* in, size_t len, char* out)
{
int i;
int blockNum;
int aesInLen;
char* aesIn;
AES_KEY aes; // 设置加密密钥
if (AES_set_encrypt_key(key, 128, &aes) < 0)
return -1;
// 判断原始数据长度是否AES_BLOCK_SIZE的整数倍
if ((len % AES_BLOCK_SIZE) != 0)
{
blockNum = len / AES_BLOCK_SIZE + 1;
aesInLen = blockNum * AES_BLOCK_SIZE;
aesIn = (char*)calloc(aesInLen, 1);
memcpy(aesIn, in, len);
}
else
{
blockNum = len / AES_BLOCK_SIZE;
aesInLen = len;
aesIn = (char*)calloc(aesInLen, 1);
memcpy(aesIn, in, len);
} // 由于ECB每次只处理AES_BLOCK_SIZE大小的数据,所以通过循环完成所有数据的加密
for (i = 0; i < blockNum; i++)
{
AES_ecb_encrypt((unsigned char*)aesIn, (unsigned char*)out, &aes, AES_ENCRYPT);
aesIn += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
} // 释放内存
// free(aesIn);
// 返回填充后加密数据的长度
return aesInLen;
} // AES ECB 模式解密
// 参数:
// - in: 待解密的数据
// - len: 待解密数据的长度
// - out: 存放解密结果的缓冲区
// 返回值:
// - 成功返回0,失败返回-1
int openssl_aes_ecb_decrypt(char* in, size_t len, char* out)
{
unsigned int i;
AES_KEY aes;
// 设置解密密钥
if (AES_set_decrypt_key(key, 128, &aes) < 0)
{
return -1;
}
// 循环解密每个数据块
for (i = 0; i < len / AES_BLOCK_SIZE; i++)
{
AES_ecb_encrypt((unsigned char*)in, (unsigned char*)out, &aes, AES_DECRYPT);
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
// 返回成功
return 0;
}

当需要对数据加密时,首先打开被加密文件这里我们打开的时csdn.zip文件,加密后会写出为csdn.ecb文件;

int main(int argc, char* argv[])
{
// 存放填充字节数的数组
char offset[4] = { '0' }; char* src = nullptr, *dst = nullptr;
int inlen, outlen, size;
FILE* srcFile, *dstFile; // 打开被加密源文件
srcFile = fopen("d://comp/csdn.zip", "rb"); // 加密后写出文件
dstFile = fopen("d://comp/csdn.ecb", "wb+"); // 获取文件大小
fseek(srcFile, 0, SEEK_END);
inlen = ftell(srcFile);
if (inlen < 0)
{
return 0;
}
fseek(srcFile, 0, SEEK_SET); // -------------------------------------------------------
// 开始加密
src = (char*)calloc(inlen, 1);
size = fread(src, 1, inlen, srcFile);
std::cout << "读入字节: " << size << std::endl; // 输出变量申请的空间额外增加16字节
outlen = (inlen / 16 + 1) * 16;
dst = (char*)calloc(outlen, 1); // ECB加密
size = openssl_aes_ecb_enrypt(src, inlen, dst);
sprintf(offset, "%d", size - inlen);
fwrite(offset, sizeof(char), 4, dstFile); // -------------------------------------------------------
// 输出加密后的文件或者解密后的文件,文件大小应与原始文件一致
size = fwrite(dst, 1, size, dstFile);
std::cout << "输出文件大小: " << size << std::endl; fcloseall();
free(src);
free(dst);
system("pause");
return 0;
}

运行后输出效果图如下所示;

解密时同样需要打开文件,将加密文件csdn.ecb打开,并解密输出成csdnde.zip文件;

int main(int argc, char* argv[])
{
// 存放填充字节数的数组
char offset[4] = { '0' }; char* src = nullptr, *dst = nullptr;
int inlen, outlen, size;
FILE* srcFile, *dstFile; // 打开加密后的文件
srcFile = fopen("d://comp/csdn.ecb", "rb"); // 解密后写出的文件
dstFile = fopen("d://comp/csdnde.zip", "wb+"); // 获取文件大小
fseek(srcFile, 0, SEEK_END);
inlen = ftell(srcFile);
if (inlen < 0)
{
return 0;
}
fseek(srcFile, 0, SEEK_SET); // -------------------------------------------------------
fread(offset, sizeof(char), 4, srcFile);
inlen -= 4;
src = (char*)calloc(inlen, 1); // 从加密后的文件中获取填充的字节数
size = fread(src, 1, inlen, srcFile);
std::cout << "读入字节: " << size << std::endl; // 得到原始文件的大小
size = size - atoi(offset); outlen = (inlen / 16 + 1) * 16;
dst = (char*)calloc(outlen, 1); // 解密
openssl_aes_ecb_decrypt(src, inlen, dst); // ------------------------------------------------------- // 输出加密后的文件或者解密后的文件,文件大小应与原始文件一致
size = fwrite(dst, 1, size, dstFile);
std::cout << "输出文件大小: " << size << std::endl; fcloseall();
free(src);
free(dst);
system("pause");
return 0;
}

运行后输出效果图如下所示;

OpenSSL 使用AES对文件加解密的更多相关文章

  1. L脚本语言实现文件加解密

    L脚本语言中能够对内存对象进行AES加解密.我们能够非常easy地实现文件加解密 #scp #定义一个秘钥字符串 定义:字符串,str1,abcdefg 打开:文件,file1,c:\1.txt 打开 ...

  2. .net core中使用openssl的公钥私钥进行加解密

    这篇博文分享的是 C#中使用OpenSSL的公钥加密/私钥解密 一文中的解决方法在 .net core 中的改进.之前的博文针对的是 .NET Framework ,加解密用的是 RSACryptoS ...

  3. Asp.Net Core 2.0 项目实战(7)MD5加密、AES&DES对称加解密

    本文目录 1. 摘要 2. MD5加密封装 3. AES的加密.解密 4. DES加密/解密 5. 总结 1.  摘要 C#中常用的一些加密和解密方案,如:md5加密.RSA加密与解密和DES加密等, ...

  4. python 实现 AES ECB模式加解密

    AES ECB模式加解密使用cryptopp完成AES的ECB模式进行加解密. AES加密数据块分组长度必须为128比特,密钥长度可以是128比特.192比特.256比特中的任意一个.(8比特 == ...

  5. JAVA AES文件加解密

    AES加解密算法,代码如下: /** * Created by hua on 2017/6/30. */ import javax.crypto.Cipher; import javax.crypto ...

  6. linux以下C 利用openssl的AES库加密,解密

    OpenSSL提供了AES加解密算法的API const char *AES_options(void); AES算法状态,是所有支持或者是部分支持. 返回值:"aes(full)" ...

  7. C#调用Crypto++库AES ECB CBC加解密

    本文章使用上一篇<C#调用C++类库例子>的项目代码作为Demo.本文中,C#将调用C++的Crypto++库,实现AES的ECB和CBC加解密. 一.下载Crypto 1.进入Crypt ...

  8. Java 使用AES/CBC/PKCS7Padding 加解密字符串

    介于java 不支持PKCS7Padding,只支持PKCS5Padding 但是PKCS7Padding 和 PKCS5Padding 没有什么区别要实现在java端用PKCS7Padding填充, ...

  9. AES CBC/CTR 加解密原理

    So, lets look at how CBC works first. The following picture shows the encryption when using CBC (in ...

  10. openssl:AES CBC PKCS5 加解密 (C/GOLANG)

    #include <openssl/aes.h> /* AES_CBC_PKCS5_Encrypt * 入参: * src:明文 * srcLen:明文长度 * key:密钥 长度只能是1 ...

随机推荐

  1. 八 Appium常用方法介绍(转)

    由于appium是扩展了Webdriver协议,所以可以使用webdriver提供的方法,比如在处理webview页面,完全可以使用webdriver中的方法.当然在原生应用中,也可以使用. 1.元素 ...

  2. loader的三种配置方式

    在这篇 webpack处理css资源 文章中使用几个常用的loader 来编译 css 代码. 但其实 loader 的配置方式不止一种,一起来看看其它方式~ 在 webpack.config.js ...

  3. 基于Prometheus搭建监控平台

    目录 前言 配置server单节点 prometheus.service 配置node节点 配置mysql监控 在数据库中添加exporter账户 修改mysql_exporter的配置 添加serv ...

  4. 数据结构之B树

    1 引言 B-tree,B即Balanced,是自平衡的多叉搜索树,用于组织和存储大量数据,以及数据库和文件系统等需要高效查找和插入操作的应用中. 为什么是"大量数据"?当主存不足 ...

  5. 6、Mybatis之高级查询

    6.1.创建接口.映射文件和测试类 ++++++++++++++++++++++++++分割线++++++++++++++++++++++++++ 注意namespace属性值为对应接口的全限定类名 ...

  6. centos7.X安装nginx – 东凭渭水流

    1.安装nginx需要使用root用户 2.配置nginx源 rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release ...

  7. MAUI+Blazor混合应用开发示例

    前言 笔者之前在公司搭建过一套生产管理系统,该系统要求能和硬件进行串口通信,同时又要提供后台信息查询.笔者给出的解决方案就是:MAUI + Blazor,这样只需要提供一套UI,就能满足桌面端.移动端 ...

  8. 京东获得JD商品详情 API 返回值说明

    ​ item_get-获得JD商品详情  API测试 onebound.jd.item_get 公共参数 名称 类型 必须 描述 key String 是 调用key(必须以GET方式拼接在URL中) ...

  9. 入门篇-其之一-第一个Java程序

    ️注意: 本文中包含实际操作,需要安装JDK.如果需要安装JDK,请按照这篇文章的步骤进行安装:点我查看JDK安装教程 小白可以多看几遍这篇文章,多敲几次代码 前面我们已经安装了JDK,接下来就是写一 ...

  10. Python/Java/Php/C#/Go/C/C++这几个主力语言,谁到底真的不行

    1.前言 阿里最近又进行了史诗级的大裁员,IT行业肉眼可见的持续性衰退与没落.当潮水退却,才能看出谁在裸泳.作为当今计算机编程界的几大主力语言,谁才真正的裸泳者呢? 2.描述 1.Python: Py ...