`

RSA公钥私钥在在实际应用的具体运用

阅读更多

  在《在Linux下如何使用openssl生成RSA公钥和私钥对》一文中,讲述了在Linux环境下如何生成RSA公钥和私钥,但在Java中,我们又是如何去很好的用它们呢?下面我来看下两个案例,特别是RSA私钥的生成是有输入密码的(在生产环境上一般都应该是这样用的),即在产生密钥对时有输入密码,如输出了12345678。


一.加签验签

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.Security;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.util.Arrays;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PasswordFinder;
import org.bouncycastle.util.encoders.Hex;

public class SignatureExample {

    public static void main(String [] args) throws Exception {
        Security.addProvider(new BouncyCastleProvider());

        String message = "hello world";
        File privateKey = new File("C:/test/key");
        KeyPair keyPair = readKeyPair(privateKey, "12345678".toCharArray());

        Signature signature = Signature.getInstance("SHA256WithRSAEncryption");
        signature.initSign(keyPair.getPrivate());
        signature.update(message.getBytes());
        byte [] signatureBytes = signature.sign();
        System.out.println(new String(Hex.encode(signatureBytes)));

        Signature verifier = Signature.getInstance("SHA256WithRSAEncryption");
        verifier.initVerify(keyPair.getPublic());
        verifier.update(message.getBytes());
        if (verifier.verify(signatureBytes)) {
            System.out.println("Signature is valid");
        } else {
            System.out.println("Signature is invalid");
        }
    }

    private static KeyPair readKeyPair(File privateKey, char [] keyPassword) throws IOException {
        FileReader fileReader = new FileReader(privateKey);
        PEMReader r = new PEMReader(fileReader, new DefaultPasswordFinder(keyPassword));
        try {
            return (KeyPair) r.readObject();
        } catch (IOException ex) {
            throw new IOException("The private key could not be decrypted", ex);
        } finally {
            r.close();
            fileReader.close();
        }
    }

    private static class DefaultPasswordFinder implements PasswordFinder {

        private final char [] password;

        private DefaultPasswordFinder(char [] password) {
            this.password = password;
        }

        @Override
        public char[] getPassword() {
            return Arrays.copyOf(password, password.length);
        }
    } 
}

 

二.通过JSch上传文件到SFTP,并从SFTP服务器上下载

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.io.Closeables;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;

public class SftpUtil {
    
    private final static Logger logger = LoggerFactory.getLogger(SftpUtil.class);
	private final static String STYLE_yyyyMMdd = "yyyyMMdd";
    
    public static String getCurrentDir() {
        return new SimpleDateFormat(STYLE_yyyyMMdd).format(new Date());
    }
    
    private static boolean isDirExist(ChannelSftp sftp, String directory) {
        
        boolean isDirExistFlag = false;
        try {
            SftpATTRS sftpATTRS = sftp.lstat(directory);
            isDirExistFlag = sftpATTRS.isDir();
        }catch(Exception e) {
            isDirExistFlag = false;
        }
        return isDirExistFlag;
    }
    
    private static boolean createDir(ChannelSftp sftp, String dirPath) {
        
        boolean res = false;
        try {
            sftp.cd("/");
            if(isDirExist(sftp, dirPath)) {
                return true;
            }
            String pathArray[] = dirPath.split("/");
            for(String path : pathArray) {
                if(path.equals("")) {
                    continue;
                }
                if(isDirExist(sftp, path)) {
                    sftp.cd(path);
                }else {
                    sftp.mkdir(path);
                    sftp.cd(path);
                }
            }
            res = true;
        }catch(Exception e) {
            res = false;
            logger.warn("创建目录异常!", e);
        }finally {
            try {
                sftp.cd("/");
            } catch (SftpException e) {
                logger.warn("切换到根目录异常!", e);
            }
        }
        return res;
    }
    
    /**
     * 上传文件
     */
    public static void upload(String user, String ip, int port, String password, String privateKeyPath, String passPhrase, String remoteFileName,
            String remoteFilePath, String localFileName) throws Exception {
        ChannelSftp sftp = null;
        FileInputStream input = null;
        Session sshSession = null;
        try {
            JSch jsch = new JSch();
            sshSession = jsch.getSession(user, ip, port);
            // 判断鉴权方式
            if(StringUtils.isNotEmpty(password)) {
                sshSession.setPassword(password);
            }else if(StringUtils.isNotEmpty(passPhrase)){
                jsch.addIdentity(privateKeyPath, passPhrase);
            }else {
                jsch.addIdentity(privateKeyPath);
            }
            sshSession.setConfig("StrictHostKeyChecking", "no");
            sshSession.connect();
            Channel channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
            if (sftp != null && sftp.isConnected()) {
                File file = new File(localFileName);
                input = new FileInputStream(file);
                if(remoteFilePath != null && StringUtils.isNotEmpty(remoteFilePath.trim())) {
                    if(createDir(sftp, remoteFilePath.trim())) {
                        sftp.cd(remoteFilePath.trim());
                    }
                }
                sftp.put(input, remoteFileName);
                sftp.quit();
            }
        } finally {
            if (input != null) {
                try {
                    Closeables.close(input, false);
                } finally {
                    input = null;
                }
            }
            if (sftp != null) {
                try {
                    sftp.disconnect();
                } finally {
                    sftp = null;
                }
            }
            if (sshSession != null) {
                try {
                    sshSession.disconnect();
                } finally {
                    sshSession = null;
                }
            }
        }
    }

    /**
     * 下载文件
     */
    public static void download(String user, String ip, int port, String password, String privateKeyPath, String passPhrase, String remoteFileName,
            String remoteFilePath, String localFileName) throws Exception {
        ChannelSftp sftp = null;
        OutputStream output = null;
        Session sshSession = null;
        try {
            JSch jsch = new JSch();
            sshSession = jsch.getSession(user, ip, port);
            // 判断鉴权方式
            if(StringUtils.isNotEmpty(password)) {
                sshSession.setPassword(password);
            }else if(StringUtils.isNotEmpty(passPhrase)){
                jsch.addIdentity(privateKeyPath, passPhrase);
            }else {
                jsch.addIdentity(privateKeyPath);
            }
            sshSession.setConfig("StrictHostKeyChecking", "no");
            sshSession.connect();
            Channel channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
            if (sftp != null && sftp.isConnected()) {
                if(remoteFilePath != null && StringUtils.isNotEmpty(remoteFilePath.trim())) {
                    if(createDir(sftp, remoteFilePath.trim())) {
                        sftp.cd(remoteFilePath.trim());
                    }
                }
                output = new FileOutputStream(localFileName, true);
                sftp.get(remoteFileName, output);
                sftp.quit();
            }
        } finally {
            if (output != null) {
                try {
                    Closeables.close(output, false);
                } finally {
                    output = null;
                }
            }
            if (sftp != null) {
                try {
                    sftp.disconnect();
                } finally {
                    sftp = null;
                }
            }
            if (sshSession != null) {
                try {
                    sshSession.disconnect();
                } finally {
                    sshSession = null;
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        
		//upload("sftpuser", "10.107.97.20", 57001, null, "C:/Users/bijian/Desktop/test/key", "123456", "a.txt", getCurrentDir(), "C:/Users/bijian/Desktop/bijian.txt");
        download("sftpuser", "10.107.97.20", 57001, null, "C:/Users/bijian/Desktop/test/key", "123456", "b.txt", getCurrentDir(), "C:/Users/bijian/Desktop/bijian02.txt");
		
		//upload("sftpuser", "10.107.97.20", 57001, "12345678", null, null, "a.txt", getCurrentDir(), "C:/Users/bijian/Desktop/bijian.txt");
        download("sftpuser", "10.107.97.20", 57001, "12345678", null, null, "b.txt", getCurrentDir(), "C:/Users/bijian/Desktop/bijian02.txt");
    }
}

 

参考文章:https://stackoverflow.com/questions/1580012/using-a-pem-encoded-encrypted-private-key-to-sign-a-message-natively

  • 大小: 79 KB
分享到:
评论

相关推荐

    Delphi RSA加解密【支持RSA公钥加密私钥解密,RSA私钥加密公钥解密,秘钥格式支持PKCS8和PKCS1】D7~XE10可用

    在实际应用中,公钥可以公开,而私钥必须保密,确保数据的安全性。 PKCS(Public-Key Cryptography Standards)是由RSA Security公司制定的一系列标准,其中PKCS#1定义了RSA的加密和签名格式,而PKCS#8则规定了私钥...

    Go-gorsa支持rsa公钥加密私钥解密;支持rsa公钥解密私钥加密

    在RSA中,一对密钥包括公钥和私钥,公钥用于加密,私钥用于解密。这样,只有拥有私钥的一方才能解密由公钥加密的信息,从而保证了数据的安全性。 在gorsa库中,我们可以看到以下关键知识点: 1. **密钥对生成**:...

    asp.net RSA 私钥加密公钥解密 能解 php Java 实现RSA加密互通

    在实际应用中,加密和解密的过程如下: 1. ASP.NET端使用私钥进行加密,生成加密后的数据。 2. 数据通过安全的渠道传递给PHP或Java端。 3. PHP或Java端使用对应的公钥尝试解密数据,如果成功,说明密钥匹配且加密...

    基于.net的RSA私钥加密 公钥解密的源码

    在实际应用中,我们还需要注意一些安全最佳实践: - **密钥长度**:为了提供足够的安全性,密钥长度不应低于2048位。更长的密钥虽然更安全,但也会增加计算成本。 - **密钥存储**:私钥应妥善保管,避免泄露。可以...

    RSA在C#和java中的应用

    在实际应用中,我们通常会将公钥存储在一个安全的地方,例如服务器上,客户端则使用公钥进行加密,服务器接收到加密数据后用私钥进行解密。反之,如果服务器需要向客户端发送安全信息,可以用私钥加密,客户端用公钥...

    基于.net的RSA私钥加密 公钥解密的源码.rar

    在实际应用中,公钥通常可以公开,而私钥必须安全存储。公钥可以通过不安全的通道传递给对方,而私钥则需要在本地安全保存。.NET提供了证书(X509Certificate2)来帮助管理公钥/私钥对,以确保安全性。 5. **性能...

    基于.net的RSA私钥加密 公钥解密的源码(值得下载)

    5. **处理加密和解密的异常**:在实际应用中,需要处理可能出现的异常,如密钥不匹配、数据损坏等。 这个源码示例可能包含了以上步骤的详细实现,并提供了如何在.NET环境中使用RSA加密和解密的代码示例。通过学习和...

    rsa加密前后端交互.前端加密后端解密

    在实际应用中,可能会结合HTTPS协议,利用SSL/TLS来提供额外的传输层安全保障。HTTPS在TCP/IP层面上提供加密,而RSA则在应用层提供数据加密,两者的结合可以有效防止中间人攻击。 在文章...

    MATLAB设计_RSA公钥加密和签名演示原理.zip

    本资源“MATLAB设计_RSA公钥加密和签名演示原理.zip”提供了一个使用MATLAB实现RSA加密和签名的实例,对于学习和理解RSA算法以及在MATLAB中的应用非常有帮助。 RSA算法是由Ron Rivest、Adi Shamir和Leonard Adleman...

    RSA加密演示

    RSA加密算法是一种非对称加密技术,...通过这个项目,开发者不仅可以学习到RSA加密算法的基本原理,还能掌握在.NET环境中如何实际应用这些知识。这有助于理解非对称加密的工作方式,并且在设计安全系统时能够灵活运用。

    中国剩余定理CRT在RSA中的运用

    中国剩余定理在RSA算法中的应用,不仅从理论上证明了其可行性,而且在实际硬件设计中也取得了显著的效果。通过对长整数模运算的高效处理和对CRT的充分利用,使得RSA加密算法在安全性和性能之间达到了更好的平衡。...

    用大数库Miracl实现的RSA

    在实际应用中,还需要考虑RSA的安全性和效率问题。随着计算技术的发展,破解RSA的可能性逐渐增大,因此通常需要使用足够大的密钥长度,如2048位或更长。同时,为了提高效率,可以采用优化的算法,如Blinding技术防止...

    java 使用RSA生成公私钥对、加解密、及签名验签

    在实际应用中,通常会将公钥和私钥保存到文件或数据库中,以便后续使用。Java提供了`java.io`和`java.security.KeyStore`类来帮助我们读写和管理这些密钥。 在提供的压缩包文件"rsa"中,可能包含了实现这些功能的...

    RSA算法工具 RSA算法

    在实际应用中,RSA算法的过程如下: 1. 密钥生成:随机选择两个大素数p和q,计算它们的乘积n=p*q。接着计算欧拉函数φ(n)=(p-1)*(q-1)。再选取一个整数e,要求1φ(n)且e与φ(n)互质。最后,通过扩展欧几里得算法找出...

    RSA 前端加密C#后端解密(两套可用程序)

    在实际应用中,为了保证安全,通常会使用OAEP(Optimal Asymmetric Encryption Padding)或其他填充模式,以防止某些攻击策略。此外,由于RSA仅适用于小块数据加密,大段的数据通常会先被分割,然后分别用RSA加密,...

    rsa.rar_asp rsa_asp 加密_rsa_test.asp_vbs解密

    2. `test.htm` - 这可能是一个测试页面,用于演示如何在实际应用中使用`clsRsa.asp`类。它会展示如何在ASP脚本中引入加密类,并对字符串进行加密和解密操作。 以下是如何在ASP中使用VBScript实现RSA加密和解密的...

    RSA算法工具

    RSA算法工具是一款基于RSA加密算法的应用程序,旨在帮助用户更轻松地进行非对称加密操作。RSA算法,全称为Rivest-Shamir-Adleman算法,是1977年由...在实际应用中,用户应妥善保管私钥,避免泄露,以确保数据的安全。

    RSA算法的C++实现软件

    在实际应用中,RSA算法的效率相对较低,不适合对大量数据进行直接加密,通常用于加密小块数据或密钥交换。此外,为了增强安全性,通常会结合对称加密算法,如AES,先用对称加密算法加密大量数据,然后用RSA加密对称...

Global site tag (gtag.js) - Google Analytics