常用加解密原理及实际使用

发布于:2025-02-22 ⋅ 阅读:(15) ⋅ 点赞:(0)

AES加解密

在Java中,可以使用javax.crypto包来实现AES-256加密和解密,使用java.security包来实现RSA-2048加密和解密。以下是一个简单的示例,展示了如何使用AES-256和RSA-2048进行加密和解密。

样例

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.util.Base64;

public class AESExample {

    public static void main(String[] args) throws Exception {
        String originalText = "Hello, AES-256!";

        // 生成AES密钥
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128); // 256位密钥,长度限制,换128【确保你的Java运行环境支持AES-256和RSA-2048。某些旧版本的Java可能需要安装额外的安全策略文件(如JCE Unlimited Strength Jurisdiction Policy Files)来支持256位密钥。】
        SecretKey secretKey = keyGen.generateKey();

        // 加密
        String encryptedText = encrypt(originalText, secretKey);
        System.out.println("Encrypted: " + encryptedText);

        // 解密
        String decryptedText = decrypt(encryptedText, secretKey);
        System.out.println("Decrypted: " + decryptedText);
    }

    public static String encrypt(String plainText, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    public static String decrypt(String encryptedText, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decryptedBytes);
    }
}

WEB中RSA加解密

在 Web 开发中,使用 RSA 实现安全信息传输的核心原理是利用 RSA 的非对称加密特性,确保数据在传输过程中的机密性、完整性和身份验证。以下是 RSA 在 Web 开发中的应用原理和实现步骤:

1. RSA 的基本原理

RSA 是一种非对称加密算法,它使用一对密钥:

  • 公钥(Public Key):用于加密数据,可以公开分享。
  • 私钥(Private Key):用于解密数据,必须严格保密。

RSA 的核心特性:

  • 用公钥加密的数据,只能用对应的私钥解密。
  • 用私钥加密的数据,只能用对应的公钥解密(通常用于数字签名)。

2. Web 开发中 RSA 的应用场景

在 Web 开发中,RSA 通常用于以下场景:

  1. 加密敏感数据
    • 客户端使用服务器的公钥加密敏感数据(如密码、信用卡号),确保数据在传输过程中不被窃取。
    • 服务器使用私钥解密数据。
  2. 数字签名
    • 服务器使用私钥对数据进行签名,客户端使用公钥验证签名,确保数据的完整性和来源真实性。
  3. 密钥交换
    • RSA 可以用于加密对称密钥(如 AES 密钥),然后通过安全通道传输对称密钥,后续通信使用对称加密。

3. RSA 实现安全信息传输的流程

以下是一个典型的 RSA 加密传输流程:

(1) 服务器生成 RSA 密钥对
  • 服务器生成一对 RSA 密钥(公钥和私钥)。
  • 公钥可以公开分享,私钥必须严格保密。
(2) 客户端获取服务器的公钥
  • 客户端通过 HTTPS 请求从服务器获取公钥。
  • 公钥可以以 PEM 或 JWK 格式传输。
(3) 客户端加密数据
  • 客户端使用服务器的公钥加密敏感数据(如用户密码)。
  • 加密后的数据称为密文。
(4) 客户端发送密文到服务器
  • 客户端将密文通过 HTTPS 发送到服务器。
(5) 服务器解密数据
  • 服务器使用私钥解密密文,获取原始数据。

4. 代码示例

import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Base64;

public class RSAExample {

    public static void main(String[] args) throws Exception {
        String originalText = "Hello, RSA-2048!";

        // 生成RSA密钥对
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(2048); // 2048位密钥
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        // 加密
        String encryptedText = encrypt(originalText, publicKey);
        System.out.println("Encrypted: " + encryptedText);

        // 解密
        String decryptedText = decrypt(encryptedText, privateKey);
        System.out.println("Decrypted: " + decryptedText);
    }

    public static String encrypt(String plainText, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    public static String decrypt(String encryptedText, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decryptedBytes);
    }
}

gitlab使用RSA机制

GitLab 使用 SSH 协议来实现与 Git 仓库的安全通信。通过 SSH,用户可以在不输入用户名和密码的情况下,安全地克隆、推送和拉取代码。以下是 GitLab 的 SSH 机制详细解析:

1. SSH 的基本概念

SSH(Secure Shell)是一种加密的网络协议,用于在不安全的网络中安全地传输数据。GitLab 使用 SSH 来实现以下功能:

  • 用户认证:通过 SSH 密钥对用户进行身份验证。
  • 数据传输:加密所有 Git 操作(如 git clonegit pushgit pull)中的数据。

2. GitLab 的 SSH 认证流程

GitLab 使用 SSH 公钥认证机制,具体流程如下:

(1) 用户生成 SSH 密钥对

用户在本地生成一对 SSH 密钥(公钥和私钥):

  • 私钥:存储在用户本地,必须严格保密。
  • 公钥:可以公开,需要上传到 GitLab。
    # 生成 SSH 密钥对
    ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
    
  • -t rsa:指定密钥类型为 RSA。
  • -b 4096:指定密钥长度为 4096 位。
  • -C:添加注释(通常是用户的邮箱)。

生成的密钥默认存储在 ~/.ssh/ 目录下: - 私钥:~/.ssh/id_rsa - 公钥:~/.ssh/id_rsa.pub

(2) 用户将公钥上传到 GitLab
  1. 复制公钥内容: bash cat ~/.ssh/id_rsa.pub
  2. 登录 GitLab,进入 Profile Settings -> SSH Keys
  3. 将公钥内容粘贴到输入框中,并保存。
(3) GitLab 存储公钥

GitLab 会将用户的公钥存储在数据库中,并与用户的账户关联。

(4) 用户通过 SSH 访问 Git 仓库

当用户执行 Git 操作时(如 git clone),GitLab 会使用 SSH 协议进行认证:

  1. 用户本地 Git 客户端通过 SSH 连接到 GitLab 服务器。
  2. GitLab 服务器向客户端发送一个随机生成的字符串。
  3. 客户端使用本地私钥对字符串进行签名,并将签名发送回服务器。
  4. 服务器使用存储的公钥验证签名。
  5. 如果验证成功,用户被允许访问 Git 仓库。

3. GitLab 的 SSH URL

GitLab 仓库的 SSH URL 格式如下:

git@gitlab.example.com:username/project.git
  • git:GitLab 的 SSH 用户名。
  • gitlab.example.com:GitLab 服务器地址。
  • username/project.git:仓库路径。

    例如:

git clone git@gitlab.example.com:john/my-project.git

4. SSH 配置文件

为了简化 SSH 连接,可以在本地配置 ~/.ssh/config 文件。例如:

Host gitlab
    HostName gitlab.example.com
    User git
    IdentityFile ~/.ssh/id_rsa

配置后,可以使用别名访问 GitLab

git clone gitlab:username/project.git

5. 多 SSH 密钥管理

如果需要在同一台机器上使用多个 SSH 密钥(例如,同时访问 GitLab 和 GitHub),可以通过以下方式管理:

(1) 生成多个密钥对
# 生成 GitLab 密钥
ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f ~/.ssh/id_rsa_gitlab

# 生成 GitHub 密钥
ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f ~/.ssh/id_rsa_github
(2) 配置 ~/.ssh/config
# GitLab
Host gitlab
    HostName gitlab.example.com
    User git
    IdentityFile ~/.ssh/id_rsa_gitlab

# GitHub
Host github
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa_github
(3) 使用不同的别名访
# 访问 GitLab
git clone gitlab:username/project.git

# 访问 GitHub
git clone github:username/project.git

6. 常见问题及解决方法

(1) 权限问题
  • 确保私钥文件的权限为 600
    chmod 600 ~/.ssh/id_rsa
    
  • 确保 ~/.ssh 目录的权限为 700
    chmod 700 ~/.ssh
    
(2) SSH 认证失败
  • 检查公钥是否已正确上传到 GitLab。
  • 检查 SSH 配置文件是否正确。
  • 使用 ssh -T 测试连接:
    ssh -T git@gitlab.example.com
    

如果成功,会显示欢迎信息。

(3) 多个 Git 服务冲突
  • 确保为每个 Git 服务配置了不同的 SSH 密钥和别名。

7. 总结

GitLab 的 SSH 机制通过公钥认证实现了安全的 Git 操作。用户需要在本地生成 SSH 密钥对,并将公钥上传到 GitLab。通过 SSH,用户可以方便地克隆、推送和拉取代码,而无需每次都输入用户名和密码。

样例

import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Base64;

public class RSAExample2 {

    public static void main(String[] args) throws Exception {
        String originalText = "Hello, RSA-2048!";

        // 生成RSA密钥对
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        keyPairGen.initialize(2048); // 2048位密钥
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        // 加密
        String encryptedText = encrypt(originalText, privateKey);
        System.out.println("Encrypted: " + encryptedText);

        // 解密
        String decryptedText = decrypt(encryptedText, publicKey);
        System.out.println("Decrypted: " + decryptedText);
    }

    public static String encrypt(String plainText, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    public static String decrypt(String encryptedText, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
        return new String(decryptedBytes);
    }
}