SAP CPI:使用公钥身份验证通过Groovy进行SFTP连接

2020-08-14 04:43发布

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


已解决的问题:通过groovy(JSch)在SFTP连接中访问和使用私钥(id_rsa)

已改造的问题::通过常规脚本而不使用SFTP适配器连接到SFTP服务器时,如何使用公钥身份验证。

业务案例::我的客户有多个带有多个SFTP服务器的第三方系统。 我需要开发一个中央CPI接口,该接口将充当中间人,以将文件从任何来源传输到任何目的地。

解决方案设计:我的设计如下

1。 维护一个配置文件,其中包含源->目标和计划组合的各种列表。

2。 接口将使用SFTP适配器从默认的SFTP服务器读取此配置文件,获取源和目标组合,并开始一个接一个地处理它。

3。 现在,一旦有了源和目标,就需要在iFlow的中间进行另一个SFTP调用。 可以在脚本中轻松使用JSch类来完成此操作。 https: //blogs.sap.com/2018/04/17/access-file-from-sftp-server-in-middle-of-an-iflow/-感谢Shashank Kesarwani

4。 但是,如果使用公共密钥身份验证,如何从密钥库中获取公共密钥并将其添加到JSch隧道中。

到目前为止的进展:

1。 我设法获得了KeystoreService

com.sap.it.api.keystore.KeystoreService ks = com.sap.it.api.ITApiFactory.getApi(com.sap.it.api.keystore.KeystoreService.class,空)

2。 当我使用getKey方法时,

def privateKey = ks.getKey(" id_rsa");

我得到的原始X.509格式的密钥是这样的:(这就是我想的那样!)

RSA私钥(2048位):

模量:

公共指数:10001

私有指数:

primeP:

primeQ:

primeExponentP:

primeExponentQ:

crt_coefficient:

3。 但是,如果必须使用JSch类通过Groovy使用公共密钥身份验证,则需要添加密钥 IN OPENSSH FORMAT 作为身份

jsch.addIdentity(" id_rsa", private_key.getBytes(),public_key.getBytes(),emptyPassPhrase);

所需格式:

-RSA私钥的开始-

-RSA私钥的结尾-

问题:如何在脚本本身中将 原始X.509格式的私钥转换为OPENSSH格式?

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


已解决的问题:通过groovy(JSch)在SFTP连接中访问和使用私钥(id_rsa)

已改造的问题::通过常规脚本而不使用SFTP适配器连接到SFTP服务器时,如何使用公钥身份验证。

业务案例::我的客户有多个带有多个SFTP服务器的第三方系统。 我需要开发一个中央CPI接口,该接口将充当中间人,以将文件从任何来源传输到任何目的地。

解决方案设计:我的设计如下

1。 维护一个配置文件,其中包含源->目标和计划组合的各种列表。

2。 接口将使用SFTP适配器从默认的SFTP服务器读取此配置文件,获取源和目标组合,并开始一个接一个地处理它。

3。 现在,一旦有了源和目标,就需要在iFlow的中间进行另一个SFTP调用。 可以在脚本中轻松使用JSch类来完成此操作。 https: //blogs.sap.com/2018/04/17/access-file-from-sftp-server-in-middle-of-an-iflow/-感谢Shashank Kesarwani

4。 但是,如果使用公共密钥身份验证,如何从密钥库中获取公共密钥并将其添加到JSch隧道中。

到目前为止的进展:

1。 我设法获得了KeystoreService

com.sap.it.api.keystore.KeystoreService ks = com.sap.it.api.ITApiFactory.getApi(com.sap.it.api.keystore.KeystoreService.class,空)

2。 当我使用getKey方法时,

def privateKey = ks.getKey(" id_rsa");

我得到的原始X.509格式的密钥是这样的:(这就是我想的那样!)

RSA私钥(2048位):

模量:

公共指数:10001

私有指数:

primeP:

primeQ:

primeExponentP:

primeExponentQ:

crt_coefficient:

3。 但是,如果必须使用JSch类通过Groovy使用公共密钥身份验证,则需要添加密钥 IN OPENSSH FORMAT 作为身份

jsch.addIdentity(" id_rsa", private_key.getBytes(),public_key.getBytes(),emptyPassPhrase);

所需格式:

-RSA私钥的开始-

-RSA私钥的结尾-

问题:如何在脚本本身中将 原始X.509格式的私钥转换为OPENSSH格式?

付费偷看设置
发送
6条回答
蓋茨
1楼 · 2020-08-14 05:05.采纳回答

最终解决方案:

导入com.sap.gateway.ip.core.customdev.util.Message;
 导入java.lang.Object;
 导入java.util.HashMap;
 导入java.io.BufferedReader;
 导入java.io.IOException;
 导入java.io.InputStream;
 导入java.io.InputStreamReader;
 导入com.jcraft.jsch.Channel;
 导入com.jcraft.jsch.ChannelSftp;
 导入com.jcraft.jsch.JSch;
 导入com.jcraft.jsch.JSchException;
 导入com.jcraft.jsch.Session;
 导入com.jcraft.jsch.SftpException;
 导入com.sap.it.api.securestore.SecureStoreService;
 导入com.sap.it.api.securestore.UserCredential;
 导入com.sap.it.api.ITApiFactory;
 导入java.security.InvalidKeyException;
 导入java.security.KeyFactory;
 导入java.security.KeyPair;
 导入java.security.KeyPairGenerator;
 导入java.security.NoSuchAlgorithmException;
 导入java.security.PrivateKey;
 导入java.security.PublicKey;
 导入java.security.SecureRandom;
 导入java.security.Signature;
 导入java.security.SignatureException;
 导入java.security.spec.InvalidKeySpecException;
 导入java.security.spec.X509EncodedKeySpec;
 导入java.security.spec.RSAPrivateKeySpec;
 导入java.util.Base64;
 def消息processData(消息消息){
     def map = message.getProperties();
     def messageLog = messageLogFactory.getMessageLog(message);
     def seq = map.get(" seq");
     def sourceDirectory = map.get(" sourceDirectory");
     def sourceFileName = map.get(" sourceFileName");
     def sourceURL = map.get(" sourceURL");
     def sourceProxyType = map.get(" sourceProxyType");
     def sourceLocationId = map.get(" sourceLocationId");
     def sourceAuthentication = map.get(" sourceAuthentication");
     def sourceUserName = map.get(" sourceUserName");
     def destinationDirectory = map.get(" destinationDirectory");
     def destinationFileName = map.get(" destinationFileName");
     def destinationURL = map.get(" destinationURL");
     def destinationProxyType = map.get(" destinationProxyType");
     def destinationLocationId = map.get(" destinationLocationId");
     def destinationAuthentication = map.get(" destinationAuthentication");
     def destinationUserName = map.get(" destinationUserName");

     字符串userName = sourceUserName;
     字符串密码="";
     字符串hostName = sourceURL;
     字符串filePath = sourceFileName;
     字符串finalString ="";
 
     def keyPair;
     def privateKeyPem;
     def publicKeyPem;
     字符串privateKeyPemStr ='';
     字符串privateKeyPemStrFinal ='';
     字符串publicKeyPemStr ='';
     字符串publicKeyPemStrFinal ='';
     def privateExponent;
     def模量;
     def算法;
     byte [] getEncoded;
     def getFormat;

     com.sap.it.api.keystore.KeystoreService ks = com.sap.it.api.ITApiFactory.getApi(com.sap.it.api.keystore.KeystoreService.class,null)
     如果(ks!= null){
        //获取密钥对
         keyPair = ks.getKeyPair(" id_rsa");

        //** ----------------------------------------------  ----------------------------------- **
        //获取私钥
         def privateKey = keyPair.getPrivate();
         getEncoded = privateKey.getEncoded()
         privateKeyPem = Base64.getEncoder()。encode(getEncoded);
         privateKeyPemStr =新的String(privateKeyPem);
         privateKeyPemStrFinal =" -----开始私有密钥----- \ n";
         列= 0;
         for(n = 0; n   
hongfeng1314
2楼-- · 2020-08-14 05:01

嗨,克里巴,

是否有任何对密钥库和groovy脚本中的密钥对进行HTTP调用(客户端证书身份验证)的经验?

我正在寻找紧急解决方案,并尝试使用给定的脚本,但收到一条错误消息,提示方法
.addIdentity()无效。

真的希望你能帮助我!

关于,
Erik。

Doze时光
3楼-- · 2020-08-14 05:12

经过一些研究,发现了如何做。

1。 获取KeystoreService

 com.sap.it.api.keystore.KeystoreService ks = com.sap.it.api.ITApiFactory.getApi(com.sap.it.api.keystore.KeystoreService.class,空)

2。 使用getKey方法获取私钥/公钥

 def privateKey = ks.getKey(" id_rsa"); 

3。 获取密钥的编码部分

 byte [] getEncoded = privateKey.getEncoded()

4。 将密钥的编码部分转换为OpenSSH格式

//** -------------------------------------------  --------------------------------------------------  ----------------- **
//获取私钥
 def privateKey = keyPair.getPrivate();
 getEncoded = privateKey.getEncoded()
  
 privateKeyPem = Base64.getEncoder()。encode(getEncoded);
 privateKeyPemStr =新的String(privateKeyPem);
        
 privateKeyPemStrFinal =" ----- BEGIN RSA PRIVATE KEY -----";
 int列= 0;
 for(int n = 0; n 
 

privateKeyPemStr将具有正确格式的密钥

N-Moskvin
4楼-- · 2020-08-14 05:17

感谢分享解决方案!

致谢

Sriprasad Shivaram Bhat p>

SAP小菜
5楼-- · 2020-08-14 05:05

面对新问题。 将私钥标识添加到JSch连接时,我还需要添加公钥。 因此,我目前正在尝试从密钥对中获取公钥和私钥,并将它们添加到JSch连接中。

未经测试的代码:

1。 获取密钥对并从中获取公钥和私钥

//获取密钥对
 def keyPair = ks.getKeyPair(" id_rsa");

//** ----------------------------------------------  ------------------------------------------- **
//获取公钥
 publicKey = keyPair.getPublic();
 getEncoded = publicKey.getEncoded()
 publicKeyPem = Base64.getEncoder()。encode(getEncoded);
 publicKeyPemStr =新的String(publicKeyPem);
 publicKeyPemStrFinal =" ----- BEGIN RSA公钥-----";
 int列= 0;
 for(int n = 0; n 
 

2。 将两个密钥都添加到JSch会话中

 jsch.addIdentity(" id_rsa",privateKeyPemStrFinal.getBytes(),publicKeyPemStrFinal.getBytes(),emptyPassPhrase)
闻人可可
6楼-- · 2020-08-14 05:16

不幸的是,仍然缺少一些东西。 即使将私钥和公钥设置为身份,我仍然会收到"验证失败"错误

https://epaul.github.io/jsch-documentation/simple.javadoc/com/jcraft/jsch/JSch.html#addIdentity-java.lang.String-byte :A-byte:A-byte:A-

一周热门 更多>