【论文笔记】检测工具进阶——结合静态分析的动态分析工具

本文主要是介绍【论文笔记】检测工具进阶——结合静态分析的动态分析工具,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文目标:精度论文 “CRYLOGGER: Detecting Crypto Misuses Dynamically” 。

针对密码算法的 API 误用,本文算是对上一篇 CryptoGuard 的改进版,实现了一个开源的动态和静态结合的自动检测工具。该论文发布于 2020 年的 S&P ,点击即可免费获取该工具,基准测试工具同 CryptoGuard 使用的论文相同,这里就放 CryptoGuard 实现的基准测试工具链接吧!研究就是层层递进的过程,我们都站在巨人的肩膀上,下一步该向哪儿爬,全在我们一念之间~

念叨

      • 一念之间:现在的密码算法怎么样了?
      • 二念之间:热门的 “自动检测”
      • 三念之间:给通用加密库定规则


一念之间:现在的密码算法怎么样了?

对于一个密码算法来说,能保证系统安全最重要的一点就是保证密钥的安全。从算法角度上讲,要保障系统机密性的话,就得关注加密算法;要保障系统完整性的话,就得关注加密 Hash 函数。

当然,研究这些基础加密算法的学者有很多,但至今也没能找到一个完全安全的加密算法。即便能够确保一个算法完全正确且安全,我们也无法保证这个算法的实现过程毫无漏洞,比如说误用。

举个具体的例子🌰吧:椭圆曲线加密算法的理论似乎很强悍,像我们的身份证就使用了这种算法去做加密,但早在 2012 年,就有学者利用 OpenSSL 的算法 bug 获取到了椭圆曲线加密算法的完整私钥。连密钥都拿到了,系统估计也就没啥安全性可言了。

抛开算法的理论层面,从上述提到的算法实现上探究,一些伴随着加密的新问题便显现了出来。2013 年就有学者调研出:从 Google Play Store 上下载的 88% 个 Android apps 至少有一种加密误用。具体而言,在保障系统机密性的层面上,一些 apps 使用硬编码密钥进行加密,而不是真正的随机密钥;在保障系统完整性的层面上,一些 Android apps 的哈希函数可能发生冲突,例如 SHA1 。

近年来,研究者们致力于分析各种情况下的密码误用。
① 堆栈溢出获取的代码片段不安全。通过堆栈溢出,有研究者获取了一些 Android apps 98%的代码片段,并分析发现它们大多存在严重的加密问题。
② 应用程序编程接口(API)太过复杂,这是 Java 中加密误用的主要根源。因为 API 复杂,所以开发人员不得不关注一些低级决策——比如选择加密算法的填充类型——而不是专注于高级任务。
③ 一些 Python 的加密库不够完善。研究者们发现 Python 加密库的文档不清不楚、代码示例不足、API 中默认配置也有误。
④ 第三方库不安全。Android 中 90% 的加密误用源自第三方库。

解决问题的前提是,要找到问题,所以检测工具就是这么产生的。由于上一篇的 CryptoGuard 自称是第一个最好的静态分析工具,因此,作者大概是读过 CryptoGuard 之后产生了新的 idea ,立刻反手做了第一个动态检测工具。接下来,作者从密码算法的 API 误用着手,针对一些常量,改进了 CryptoGuard 静态分析工具。

具体来说,CRYLOGGER 就是在 CryptoGuard 的基础上做了动态分析方法和静态分析方法相结合的策略,在线记录log文件,离线检测分析,使得整个工具更加完善。下面我们一点一点来分析 CRYLOGGER ~


二念之间:热门的 “自动检测”

自动化越来越流行,检测工具也不例外,在介绍动态 CRYLOGGER 之前,让我们先谈一谈热门的 “自动检测” 吧!这是设计 CRYLOGGER 工具的关键步骤。

一般来说, “自动检测” 的思想主要是这么两个方面:(1)定义一组加密规则;(2)通过验证加密 API 的传参,检查 apps 是否遵守了这些规则。

💨定规则 (依据)
◾ 论文里的 加密算法或其错误配置 造成的漏洞。
◾ NIST、IETF 等组织和机构定义的加密相关标准。

可以举个例子🌰:① 设置用于加密的最小密钥大小,例如 RSA 是 2048 位;② 设置用于密钥推导的最小迭代次数,例如 PKCS#5 是 1000 次。

💨守规则
◾ 静态方法:主要利用程序切片检查加密 API 的传参,例:CrySL、CryptoLint、 CryptoGuard、MalloDroid、 CogniCrypt、CMA等。
优势:不需执行,代码全分析,可扩展;
劣势:误报。
像上一篇提到的 CryptoGuard 就有很多误报因素,如分支过早被修剪(大概是上一篇提到的控制裁剪深度问题)、遗漏需动态加载的部分代码(大概是上一篇提到的幻想库问题)。
◾ 动态方法:
优势:需在运行时触发加密 API ,少误报;
劣势:难以使用,不支持静态方法的加密规则。

总之,现状就是探索静态分析方法的人多,而探索动态分析方法的人少,这也是作者发现的研究缺口。

来看看 CRYLOGGER 怎么运用自动检测的吧:

在这里插入图片描述

还是上面说的两个方面:定规则、守规则。

  1. logger 定规则:扩展 Java 加密库 ═▶ 跟踪(检测)加密算法的 API 调用 ═▶ log 文件记录(存储)必须用于检查加密规则的相关参数值。
    例如:上图中的 logger 保存 apps 代码的 消息摘要(SHA1) 和 对称加密(AES) 的算法名;
  2. checker 守规则:在线执行后 ═▶ 离线分析 log 文件 ═▶ 生成 apps 违规的规则列表。
    需要一组检查过程,每个检查过程包含很多加密规则,例如上图中的(红色感叹号), checker 发现 apps 使用了不安全的 Hash 函数 (SHA1) 作为消息摘要算法。

为什么要分离成上述的两个过程?
(1) 加密库的参数稳定,即不太可能添加新参数,就比如说,密钥推导算法的关键参数只是 盐值(salt) 、密码(password) 以及 迭代次数;
(2) 加密规则不确定,新规则针对新漏洞,那么当前规则就需要更新,比如 RSA 的最小 key 的大小会有变数;
(3) 加密规则上下文相关,但一些规则可能与该系统的上下文无关;
(4) 在线检查规则可能会影响性能,而离线不会,这在某些 apps 的关键响应上非常重要。

现在我们已经清楚这个工具要从哪里入手了,接下来就把这两个过程了解得更清楚一点吧!


三念之间:给通用加密库定规则

先上图:
在这里插入图片描述
🍁 图中指示了经典密码库中的七大安全点:(1)消息摘要;(2)对称加密;(3)非对称加密;(4)密钥派生;(5)随机数生成;(6)密钥存储;(7) SSL/TLS/Certif 。

当然,这里仅包含了现存的静态工具使用的类及其在Java和Android中实现的相应类,它们是误用情况最严重的,但这个库仍不够完整。因此,作者加强了规则的可扩展性,使用者可以任意添加其需要的检测规则。

现在来解释这个图的具体含义:

(1) 💨 消息摘要 —— 用于检查数据完整性

【输入】(任意长)data↓
Hash函数↓
【输出】(固定长)Hash  = 摘要

【重点参数】
alg :用作Hash函数的算法,例如, SHA1 、 SHA256 。不同的库支持不同的算法。

(2) 💨 对称加密的分组密码

【输入】(固定长)分组数据 = size + (算法定义长短)key↓
分组加密↓
【输出】分组数据  = (加密)密文 or (解密)明文

【重点参数】
alg :用作加密和解密的算法,例如 AES。
key :密钥。
#block :固定大小的分组数据。
mode :一些操作模式,用于处理多个分组数据,例如 电子密码本模式 (ECB) 使得分组数据独立加解密;密码分组链接模式 (CBC) 使得每个明文分组都与前面的密文分组异或;密码反馈模式 (CFB) ;输出反馈模式 (OFB) ;Galois/counter (GCM) 。
iv :初始化向量,定义第一个需要异或的分组数据。
pad :用于补足分组大小的填充算法,例如 最后一个分组填充 0 的 ZEROPADDING 、PKCS#5 、 PKCS#7 。

(3) 💨 非对称加密的公钥加密算法

【发送方】				【发送方】			|	【发送方】				【发送方】↓						↑				|		↓						↑		
用接收方的公钥加密		用接收方的私钥解密	|	用发送方的私钥签名		用发送方的公钥验签		↓						↑				|		↓						↑		
【接收方】				【接收方】			|	【接收方】				【接收方】

【重点参数】
alg :用于加密的算法,例如 RSA、椭圆曲线(EC)、数字签名算法(DSA) 。
key :用到的公私钥对。
pad :算法,例如 NOPADDING、PKCS1-v1.5、PSS。

(4) 💨 密钥派生

【输入】password or passphrase↓
加 salt ↓
Hash函数↓
经固定迭代次数↓
【输出】密钥

【重点参数】
pass :输入的密码或密码短语。
salt :盐值,即随机值。
iter :用于生成密钥的固定迭代次数,迭代次数越多,越不易被暴力攻击。

(5) 💨 随机数生成
本文只假设两类算法:Secure 和 NotSecure

【重点参数】
alg :如果生成适合加密的随机数,则使用 Secure 算法,否则使用 NotSecure 算法。
out :生成随机数的字节。
seed :生成的种子。

(6) 💨 密钥存储 —— 存储加密密钥、证书等敏感内容

【重点参数】
pass :输入的密码或密码短语。

(7) 💨 SSL/TLS/Certif

【重点参数】
urlprot :HTTP 或 HTTPS 连接。
allhost :验证是否接受所有的主机名。
allcert :验证证书是否可信。
sethost :SSL/TLS 连接的主机名验证。

以上便是针对加密算法所需要关注的脆弱点。

❗等等,图中的圆圈还没介绍❗

🍁 别急,我们上一”念“中提到过,定规则有两大依据:论文里的 加密算法或其错误配置 造成的漏洞;NIST、IETF 等组织和机构定义的加密相关标准。

作者从论文和 NIST 和 IETF的 官方发布文档中搜集 CRYLOGGER 应支持的规则,并制成下表。
在这里插入图片描述
规则也太多了吧,检测会不会很麻烦啊?

不麻烦哦,作者仅制定了四种检测过程就覆盖了所有的规则哦!而且这些检测过程还是通用的,他们对于新规则也很适用(作者说的)。下面我就结合4个检测过程来和大家分享整个规则与检测过程吧:

🔴过程一:不能接受的值

一

◾ 这是最基本的检查过程,用于检查最多数量的加密规则,主要分两步:提取 log 中所有的 参数/组合参数 值;验证其相应的加密类能否使用这些参数去进行配置。(ps:密码类名就是上文“二念”里提到的 logger 所记录的算法名)

◾ 流程:log 搜集的一大波值 ═▶ 特殊规则函数 ═▶ 接受"yes" / 拒绝"no" ;

◾ 适用加密规则:

💨 R-01 不允许 apps 使用不安全的 哈希函数 ,也就是那些可以产生冲突的函数,比如 SHA1 ;

R − 01 : M e s s a g e D i g e s t . a l g ∉ { ′ S H A 1 ′ , . . } R-01: MessageDigest.alg \notin \{'SHA1', ..\} R01:MessageDigest.alg/{SHA1,..}

💨 R-02 禁止使用不安全的对称加密 算法 ,比如 Blowfish 、 DES 等;

R − 02 : S y m m E n c r y p t i o n . a l g ∉ { ′ D E S ′ , . . } R-02: SymmEncryption.alg \notin \{'DES', ..\} R02:SymmEncryption.alg/{DES,..}

💨 R-03和R-04 不允许 apps 使用 ECB 、CBC 操作模式 ,仅接受对1个数据分组使用 ECB 。。因为 ECB 将相同的明文加密形式不变,这打破了语义安全的属性,容易受到攻击;而 CBC 在 C/S 中易受 padding oracle 攻击;

R − 03 : S y m m E n c r y p t i o n . m o d e ≠ ′ E C B ′ o r S y m m E n c r y p t i o n . # b l o c k s = 1 R − 04 : S y m m E n c r y p t i o n . m o d e ≠ ′ C B C ′ R-03: SymmEncryption.mode \not = \space 'ECB' \space or \\ \space \space \space \space SymmEncryption.\#blocks = 1 \\ R-04: SymmEncryption.mode \not = \space 'CBC' \space \space \space \space \space \\ R03:SymmEncryption.mode= ECB or    SymmEncryption.#blocks=1R04:SymmEncryption.mode= CBC     

💨 R-11 要求 盐值足够大 (≥64位);

R − 11 : K e y D e r i v a t i o n . s a l t ≥ 64 b i t s R-11: KeyDerivation.salt ≥ 64 \space bits R11:KeyDerivation.salt64 bits

💨 R-13 密钥生成算法的 迭代足够多 ,防暴力攻击;

R − 13 : K e y D e r i v a t i o n . i t e r ≥ 1000 R-13: KeyDerivation.iter ≥ 1000 R13:KeyDerivation.iter1000

💨 R-14和R-15 不允许使用列入 黑名单的密码 ,增大密码破解难度;(ps:点击查看弱密码 BadPass ;得分评估来自论文 zxcvbn )

R − 14 : K e y D e r i v a t i o n . p a s s ∉ B a d P a s s R − 15 : s c o r e ( K e y D e r i v a t i o n . p a s s ) ≥ 3 R-14: KeyDerivation.pass \notin BadPass \\ R-15: score ( KeyDerivation.pass ) ≥ 3 \space R14:KeyDerivation.pass/BadPassR15:score(KeyDerivation.pass)3 

💨 R-18 不允许 apps 使用未经批准的 PRNG ,比如 java.secure.SecureRandom 就比受限的 java.util.Random 更安全;

R − 18 : R a n d o m G e n e r a t o r . a l g = ′ S e c u r e ′ R-18: RandomGenerator.alg = 'Secure' R18:RandomGenerator.alg=Secure

💨 R-19、R-20和R-21 禁止 RSA算法 的某些配置。密钥应该 ≥2048位 ,加/解密时必须使用不同于 NOPADDING 和 PKCS1-v1.5 的填充算法;

R − 19 : A s y m m E n c r y p t i o n . a l g ≠ ′ R S A ′ o r A s y m m E n c r y p t i o n . k e y ≥ 2048 b i t s R − 20 : A s y m m E n c r y p t i o n . a l g ≠ ′ R S A ′ o r A s y m m E n c r y p t i o n . p a d ≠ ′ N O P A D D I N G ′ R − 21 : A s y m m E n c r y p t i o n . a l g ≠ ′ R S A ′ o r A s y m m E n c r y p t i o n . p a d ≠ ′ P K C S 1 − v 1. 5 ′ R-19: AsymmEncryption.alg \not = \space 'RSA' \space or \\ \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space AsymmEncryption.key ≥ 2048 \space bits \\ R-20: AsymmEncryption.alg \not = \space 'RSA' \space or \\ \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space AsymmEncryption.pad \not = \space 'NOPADDING' \\ R-21: AsymmEncryption.alg \not = \space 'RSA' \space or \\ \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space AsymmEncryption.pad \not = \space 'PKCS1-v1.5' \\ R19:AsymmEncryption.alg= RSA or               AsymmEncryption.key2048 bitsR20:AsymmEncryption.alg= RSA or                               AsymmEncryption.pad= NOPADDINGR21:AsymmEncryption.alg= RSA or                             AsymmEncryption.pad= PKCS1v1.5

💨 R-22 禁止使用 HTTP 作为连接协议,要求使用 更安全的 HTTPS

R − 22 : S S L / T L S / C e r t . u r l p r o t ≠ ′ H T T P ′ R-22: SSL/TLS/Cert.urlprot \not = \space 'HTTP' R22:SSL/TLS/Cert.urlprot= HTTP

💨 R-24和R-25 要求 正确验证 主机名和证书,比如不允许接受所有主机名或所有证书;

R − 24 : S S L / T L S / C e r t . a l l h o s t = ′ F a l s e ′ R − 25 : S S L / T L S / C e r t . a l l c e r t = ′ F a l s e ′ R-24: SSL/TLS/Cert.allhost = 'False' \\ R-25: SSL/TLS/Cert.allcert = 'False' \space R24:SSL/TLS/Cert.allhost=FalseR25:SSL/TLS/Cert.allcert=False 

💨 R-26 禁止修改 标准主机名验证器 ,因为修改可能导致不安全的 SSL/TLS 通信。(ps:例子)

R − 26 : S S L / T L S / C e r t . s e t h o s t n o t a s s i g n e d R-26: SSL/TLS/Cert.sethost \space not \space assigned R26:SSL/TLS/Cert.sethost not assigned

🔴过程二:常量

二

◾ 主要验证加密类的参数是否为常量。(ps:密码类名就是上文“二念”里提到的 logger 所记录的算法名)

◾ 流程:两次执行同一 app ═▶ 两次执行的 log 中值 一致"yes" / 不一致"no" ;

◾ 适用加密规则:

💨 R-05和R-06 限制 密钥的生成 。对称加密的密钥是由 apps 随机生成的,而非硬编码常量;密钥的随机生成器应安全; (ps:R-06 验证是否真随机,使用下一检测过程

R − 05 : { S y m m E n c r y p t i o n . k e y } 1 ∩ { S y m m E n c r y p t i o n . k e y } 2 = ∅  R-05: \{ SymmEncryption.key \}_1 ∩ \\ \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \{ SymmEncryption.key \}_2 = ∅ \space R05:{SymmEncryption.key}1                   {SymmEncryption.key}2= 

💨 R-07和R-08 与上一条类似。对称加密中应使用的 IV ,而非密钥。作者认为当 IV 与某些操作模式 (如GCM) 匹配时, IV 始终随机且非常数。作者认为使用 IV 可以加强数据的保密性; (ps:R-08 验证是否真随机,使用下一检测过程

R − 07 : { S y m m E n c r y p t i o n . i v } 1 ∩ { S y m m E n c r y p t i o n . i v } 2 = ∅  R-07: \{ SymmEncryption.iv \}_1 ∩ \\ \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \{ SymmEncryption.iv \}_2 = ∅ \space R07:{SymmEncryption.iv}1                   {SymmEncryption.iv}2= 

💨 R-10 和R-05是一样的,这里针对密钥生成中使用的 盐值

R − 10 : { K e y D e r i v a t i o n . s a l t } 1 ∩ { K e y D e r i v a t i o n . s a l t } 2 = ∅  R-10: \{ KeyDerivation.salt \}_1 ∩ \\ \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \{ KeyDerivation.salt \}_2 = ∅ \space R10:{KeyDerivation.salt}1                   {KeyDerivation.salt}2= 

💨 R-17 要求 伪随机数生成器(PRNG) 的 seed 使用随机值,而非常量值。因为常量 seed 生成的数字序列可预测;

R − 17 : { R a n d o m G e n e r a t o r . s e e d } 1 ∩ { R a n d o m G e n e r a t o r . s e e d } 2 = ∅  R-17: \{ RandomGenerator.seed \}_1 ∩ \\ \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \{ RandomGenerator.seed \}_2 = ∅ \space R17:{RandomGenerator.seed}1                   {RandomGenerator.seed}2= 

💨 R-23 禁止使用 静态密码 存储密钥;

R − 23 : { K e y S t o r a g e . p a s s } 1 ∩ { K e y S t o r a g e . p a s s } 2 = ∅  R-23: \{ KeyStorage.pass \}_1 ∩ \\ \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \{ KeyStorage.pass \}_2 = ∅ \space R23:{KeyStorage.pass}1                   {KeyStorage.pass}2= 

🔴过程三:不安全的派生值
三

◾ 主要验证一个值是否真随机。(ps:密码类名就是上文“二念”里提到的 logger 所记录的算法名)

◾ 流程:确定来源 / NIST 测试 ═▶ 失败 / 成功 / 跳过;(ps:作者认为,一个 app 只要有一个 NIST 测试失败,那么该 app 就违反了规则。虽然不能保证通过测试的 app 真随机,但这也比没有考虑这种情况的静态分析方法强一点。)

◾ 适用加密规则:上述的规则 R-06R-08

R a n d o m G e n e r a t o r . a l g = ′ S e c u r e ′ ⟹ s u c c e s s R a n d o m G e n e r a t o r . a l g ≠ ′ S e c u r e ′ ⟹ f a i l u r e ∃ t ∈ N I S T t e s t s , t = ′ f a i l s ′ ⟹ f a i l u r e RandomGenerator.alg = \space ' Secure ' \implies success \\ RandomGenerator.alg \not = \space ' Secure ' \implies failure \\ \space \space \space \space \space \space \space \space \space \space \exist \space t \in NIST \space tests, t = \space ' fails ' \implies failure \\ RandomGenerator.alg= SecuresuccessRandomGenerator.alg= Securefailure           tNIST tests,t= failsfailure

🔴过程四:重用值
四

◾ 主要验证加密类的 参数/组合参数 值是否在 app 的执行过程中被重用。(ps:密码类名就是上文“二念”里提到的 logger 所记录的算法名)

◾ 流程:log 收集所有的值 ═▶ 重复"yes" / 无重复"no" ;(ps:也是静态分析方法里没有的。)

◾ 适用加密规则:

💨 R-09 不允许 重用 相同的 (密钥/ IV)对 加密不同的消息。因为重用可预测;

R − 09 : c o n t a i n s D u p l i c a t e s ( { ( S y m m E n c r y p t i o n . k e y , S y m m E n c r y p t i o n . i v ) } ) = F a l s e R-09: containsDuplicates( \\ \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \{ \space (SymmEncryption.key, \\ \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space \space SymmEncryption.iv) \space \} \space ) = False \\ R09:containsDuplicates(                   { (SymmEncryption.key,                                         SymmEncryption.iv) } )=False

💨 R-12 禁止 重用 相同盐值,因为它违背了向相应密码中添加随机性的目的;

同上 同上 同上

💨 R-16 禁止使用 固定密码 ;

同上 同上 同上

以上,规则全部阐述完毕。下面开始检测!



四念之间:检测详情

五念之间:这工具好用不?

六念之间:涉及到的逆向工程

七念之间:还是有局限性的…

这篇关于【论文笔记】检测工具进阶——结合静态分析的动态分析工具的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/687934

相关文章

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

Java数字转换工具类NumberUtil的使用

《Java数字转换工具类NumberUtil的使用》NumberUtil是一个功能强大的Java工具类,用于处理数字的各种操作,包括数值运算、格式化、随机数生成和数值判断,下面就来介绍一下Number... 目录一、NumberUtil类概述二、主要功能介绍1. 数值运算2. 格式化3. 数值判断4. 随机

使用Navicat工具比对两个数据库所有表结构的差异案例详解

《使用Navicat工具比对两个数据库所有表结构的差异案例详解》:本文主要介绍如何使用Navicat工具对比两个数据库test_old和test_new,并生成相应的DDLSQL语句,以便将te... 目录概要案例一、如图两个数据库test_old和test_new进行比较:二、开始比较总结概要公司存在多

Java中基于注解的代码生成工具MapStruct映射使用详解

《Java中基于注解的代码生成工具MapStruct映射使用详解》MapStruct作为一个基于注解的代码生成工具,为我们提供了一种更加优雅、高效的解决方案,本文主要为大家介绍了它的具体使用,感兴趣... 目录介绍优缺点优点缺点核心注解及详细使用语法说明@Mapper@Mapping@Mappings@Co

使用Python实现图片和base64转换工具

《使用Python实现图片和base64转换工具》这篇文章主要为大家详细介绍了如何使用Python中的base64模块编写一个工具,可以实现图片和Base64编码之间的转换,感兴趣的小伙伴可以了解下... 简介使用python的base64模块来实现图片和Base64编码之间的转换。可以将图片转换为Bas

使用Java实现一个解析CURL脚本小工具

《使用Java实现一个解析CURL脚本小工具》文章介绍了如何使用Java实现一个解析CURL脚本的工具,该工具可以将CURL脚本中的Header解析为KVMap结构,获取URL路径、请求类型,解析UR... 目录使用示例实现原理具体实现CurlParserUtilCurlEntityICurlHandler

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

Rsnapshot怎么用? 基于Rsync的强大Linux备份工具使用指南

《Rsnapshot怎么用?基于Rsync的强大Linux备份工具使用指南》Rsnapshot不仅可以备份本地文件,还能通过SSH备份远程文件,接下来详细介绍如何安装、配置和使用Rsnaps... Rsnapshot 是一款开源的文件系统快照工具。它结合了 Rsync 和 SSH 的能力,可以帮助你在 li