`

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
分享到:
评论

相关推荐

    信息安全概论课后习题答案总结(华南理工大学出版社)

    计算题部分要求考生运用特定的加密解密算法进行实际计算,比如使用Vigenere方案解密密文,求解RSA系统中的私钥,以及根据RSA公钥和密文求解明文等。这部分内容考察了考生对加密解密算法的理解和应用能力。

    JAVA上百实例源码以及开源项目

    产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥验证签名结果,...

    java源码包2

    产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥验证签名结果,...

    java源码包---java 源码 大量 实例

    产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥验证签名结果,...

    JAVA上百实例源码以及开源项目源代码

    产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥验证签名结果,...

    java源码包3

    产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥验证签名结果,...

    java源码包4

    产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥验证签名结果,...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥验证签名结果,...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥验证签名结果,...

Global site tag (gtag.js) - Google Analytics