diff --git a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/ExtendApiMetadata.java b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/ExtendApiMetadata.java new file mode 100644 index 00000000..ba56701f --- /dev/null +++ b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/ExtendApiMetadata.java @@ -0,0 +1,33 @@ +package org.maxkey.authz.exapi.endpoint; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.maxkey.authz.exapi.endpoint.adapter.netease.NeteaseRSATool; +import org.maxkey.pretty.impl.JsonPretty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "2-8-ExtendApi接口文档模块-元数据") +@Controller +public class ExtendApiMetadata { + final static Logger _logger = LoggerFactory.getLogger(ExtendApiMetadata.class); + + @Operation(summary = "netease qiye mail RSA Key", description = "网易企业邮箱RSA Key生成器",method="GET") + @RequestMapping( + value = "/metadata/netease/qiye/mail/rsa/gen", + method = {RequestMethod.POST, RequestMethod.GET}) + @ResponseBody + public String metadata(HttpServletRequest request,HttpServletResponse response) { + NeteaseRSATool neteaseRSATool =new NeteaseRSATool(); + neteaseRSATool.genRSAKeyPair(); + return JsonPretty.getInstance().formatln(neteaseRSATool); + } +} diff --git a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiQiye163ExmailAdapter.java b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiNeteaseQiyeMailAdapter.java similarity index 52% rename from maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiQiye163ExmailAdapter.java rename to maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiNeteaseQiyeMailAdapter.java index 4c00af5d..d4998c47 100644 --- a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiQiye163ExmailAdapter.java +++ b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/ExtendApiNeteaseQiyeMailAdapter.java @@ -17,31 +17,32 @@ package org.maxkey.authz.exapi.endpoint.adapter; -import java.io.UnsupportedEncodingException; -import java.security.interfaces.RSAPrivateKey; - +import org.apache.commons.lang3.StringUtils; import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter; -import org.maxkey.crypto.HexUtils; -import org.maxkey.crypto.RSAUtils; +import org.maxkey.authz.exapi.endpoint.adapter.netease.NeteaseRSATool; import org.maxkey.entity.Accounts; +import org.maxkey.entity.ExtraAttr; import org.maxkey.entity.ExtraAttrs; import org.maxkey.entity.apps.Apps; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.ModelAndView; + + /** * qiye.163.com * @author shimingxy * */ -public class ExtendApiQiye163ExmailAdapter extends AbstractAuthorizeAdapter { - final static Logger _logger = LoggerFactory.getLogger(ExtendApiQiye163ExmailAdapter.class); +public class ExtendApiNeteaseQiyeMailAdapter extends AbstractAuthorizeAdapter { + final static Logger _logger = LoggerFactory.getLogger(ExtendApiNeteaseQiyeMailAdapter.class); //https://entryhz.qiye.163.com - static String REDIRECT_URI - = "https://entryhz.qiye.163.com/domain/oa/Entry?domain=%s&account_name=%s&time=%s&enc=%s"; + static String REDIRECT_PARAMETER = "domain=%s&account_name=%s&time=%s&enc=%s&lang=%s"; + + static String DEFAULT_REDIRECT_URI ="https://entryhz.qiye.163.com/domain/oa/Entry"; Accounts account; - + @Override public Object generateInfo() { return null; @@ -51,38 +52,43 @@ public class ExtendApiQiye163ExmailAdapter extends AbstractAuthorizeAdapter { public ModelAndView authorize(ModelAndView modelAndView) { Apps details=(Apps)app; - //extraAttrs from Applications - ExtraAttrs extraAttrs=null; - if(details.getIsExtendAttr()==1){ - extraAttrs=new ExtraAttrs(details.getExtendAttr()); + StringBuffer redirect_uri = new StringBuffer(details.getLoginUrl()); + if(StringUtils.isNotBlank(redirect_uri)) { + if(redirect_uri.indexOf("?")>-1) { + redirect_uri.append("").append( REDIRECT_PARAMETER); + }else { + redirect_uri.append("?").append( REDIRECT_PARAMETER); + } } + //extraAttrs from App + ExtraAttrs extraAttrs=null; + if(details.getIsExtendAttr() == 1){ + extraAttrs = new ExtraAttrs(details.getExtendAttr()); + for(ExtraAttr attr : extraAttrs.getExtraAttrs()) { + redirect_uri.append("&").append(attr.getAttr()).append("=").append(attr.getValue()); + } + } + String time = System.currentTimeMillis() + ""; //域名,请使用企业自己的域名 String domain = details.getPrincipal(); - String account_name = this.userInfo.getEmail(); + String account_name = this.userInfo.getEmail().substring(0, this.userInfo.getEmail().indexOf("@")); - //String lang = "0"; + String lang = "0"; String src = account_name + domain + time; String privateKey = details.getCredentials(); - String enc = null; - try { - enc = HexUtils.bytes2HexString( - RSAUtils.sign( - src.getBytes("UTF-8"), - (RSAPrivateKey)RSAUtils.privateKey(HexUtils.hex2Bytes(privateKey)), - null) - ); - String loginUrl = String.format(REDIRECT_URI, domain,account_name,time,enc); - _logger.debug("LoginUrl {} " , loginUrl); - modelAndView.addObject("redirect_uri", loginUrl); - } catch (UnsupportedEncodingException e) { - _logger.error("UnsupportedEncodingException ", e); - } catch (Exception e) { - _logger.error("Exception ", e); - } + _logger.debug("Private Key {} " , privateKey); + + String enc = new NeteaseRSATool().generateSHA1withRSASigature(src, privateKey); + String loginUrl = String.format(redirect_uri.toString(), domain,account_name,time,enc,lang); + + _logger.debug("LoginUrl {} " , loginUrl); + modelAndView.addObject("redirect_uri", loginUrl); return modelAndView; } + + } diff --git a/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/netease/NeteaseRSATool.java b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/netease/NeteaseRSATool.java new file mode 100644 index 00000000..3d9da9b7 --- /dev/null +++ b/maxkey-protocols/maxkey-protocol-extendapi/src/main/java/org/maxkey/authz/exapi/endpoint/adapter/netease/NeteaseRSATool.java @@ -0,0 +1,310 @@ +package org.maxkey.authz.exapi.endpoint.adapter.netease; + +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +import javax.crypto.Cipher; + +import org.apache.commons.lang.ArrayUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NeteaseRSATool { + + final static Logger _logger = LoggerFactory.getLogger(NeteaseRSATool.class); + + private static final char[] bcdLookup = { '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + + private String description = "1024-bit RSA key"; + private String priKey = null; + private String pubKey = null; + + + public String bytesToHexStr(byte[] bcd) { + StringBuffer s = new StringBuffer(bcd.length * 2); + + for (int i = 0; i < bcd.length; i++) { + s.append(bcdLookup[(bcd[i] >>> 4) & 0x0f]); + s.append(bcdLookup[bcd[i] & 0x0f]); + } + + return s.toString(); + } + + public byte[] hexStrToBytes(String s) { + byte[] bytes; + + bytes = new byte[s.length() / 2]; + + for (int i = 0; i < bytes.length; i++) { + bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2), + 16); + } + + return bytes; + } + + public void genRSAKeyPair() { + KeyPairGenerator rsaKeyGen = null; + KeyPair rsaKeyPair = null; + try { + _logger.trace("Generating a pair of RSA key ... "); + rsaKeyGen = KeyPairGenerator.getInstance("RSA"); + SecureRandom random = new SecureRandom(); + random.setSeed(System.currentTimeMillis()); + + rsaKeyGen.initialize(1024, random); + + rsaKeyPair = rsaKeyGen.genKeyPair(); + PublicKey rsaPublic = rsaKeyPair.getPublic(); + PrivateKey rsaPrivate = rsaKeyPair.getPrivate(); + + pubKey = bytesToHexStr(rsaPublic.getEncoded()); + priKey = bytesToHexStr(rsaPrivate.getEncoded()); + _logger.trace("pubKey: {}" , pubKey); + _logger.trace("priKey: {}" , priKey); + _logger.trace("1024-bit RSA key GENERATED."); + } catch (Exception e) { + _logger.error("Exception genRSAKeyPair:" + e); + } + } + + public String generateSHA1withRSASigature(String src, String priKey) { + try { + byte[] pribyte = hexStrToBytes(priKey.trim()); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); + KeyFactory fac = KeyFactory.getInstance("RSA"); + RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec); + + Signature sigEng = Signature.getInstance("SHA1withRSA"); + sigEng.initSign(privateKey); + sigEng.update(src.getBytes()); + byte[] signature = sigEng.sign(); + return bytesToHexStr(signature); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public String encryptWithPriKey(String src, String priKey) { + try { + byte[] pribyte = hexStrToBytes(priKey.trim()); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); + KeyFactory fac = KeyFactory.getInstance("RSA"); + Key privateKey = fac.generatePrivate(keySpec); + + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + + byte[] bytes = src.getBytes(); + byte[] encodedByteArray = new byte[] {}; + for (int i = 0; i < bytes.length; i += 102){ + byte[] subarray = ArrayUtils.subarray(bytes, i, i + 102); + byte[] doFinal = cipher.doFinal(subarray); + encodedByteArray = ArrayUtils.addAll(encodedByteArray, doFinal); + } + return bytesToHexStr(encodedByteArray); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public boolean verifySHA1withRSASigature(String sign, String src, + String pubKeyStr) { + try { + + Signature sigEng = Signature.getInstance("SHA1withRSA"); + + byte[] pubbyte = hexStrToBytes(pubKeyStr.trim()); + + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte); + KeyFactory fac = KeyFactory.getInstance("RSA"); + RSAPublicKey pubKey = (RSAPublicKey) fac.generatePublic(keySpec); + + sigEng.initVerify(pubKey); + sigEng.update(src.getBytes()); + + byte[] sign1 = hexStrToBytes(sign); + return sigEng.verify(sign1); + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + + public String encryptLongTextWithPriKey(String src, String priKey) { + final int ENCRYPT_LENGTH = 117; + if (src.length() <= ENCRYPT_LENGTH) { + return encryptWithPriKey(src, priKey); + } + + StringBuffer sb = new StringBuffer(); + int idx = 0; + while (idx < src.length()) { + int end = idx + ENCRYPT_LENGTH > src.length() ? src.length() : idx + ENCRYPT_LENGTH; + String sub = src.substring(idx, end); + String encSub = encryptWithPriKey(sub, priKey); + sb.append(encSub); + idx += ENCRYPT_LENGTH; + } + + return sb.toString(); + } + + public String encryptWithPriKeyWithBase64(String src, String priKey) { + try { + byte[] pribyte = hexStrToBytes(priKey.trim()); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); + KeyFactory fac = KeyFactory.getInstance("RSA"); + Key privateKey = fac.generatePrivate(keySpec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + byte[] signature = cipher.doFinal(src.getBytes()); + + return Base64.getEncoder().encodeToString(signature).replaceAll("[^a-zA-Z0-9+/=]", ""); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public String encryptWithPubKey(String src, String pubKey) { + try { + byte[] pubbyte = hexStrToBytes(pubKey.trim()); + + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte); + + KeyFactory fac = KeyFactory.getInstance("RSA"); + Key publicKey = fac.generatePublic(keySpec); + + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] signature = cipher.doFinal(src.getBytes()); + + return bytesToHexStr(signature); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public String decryptWithPriKey(String enc, String priKey) { + try { + byte[] pribyte = hexStrToBytes(priKey.trim()); + + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); + KeyFactory fac = KeyFactory.getInstance("RSA"); + RSAPrivateKey privateKey = (RSAPrivateKey) fac + .generatePrivate(keySpec); + + // privateKey.getModulus() + privateKey.getPrivateExponent() + + // privateKey.getAlgorithm(); + + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + + byte[] forumcookie = hexStrToBytes(enc); + + byte[] plainText = cipher.doFinal(forumcookie); + + return bytesToHexStr(plainText); + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public String decryptWithPubKey(String enc, String pubKey) { + try { + byte[] pubbyte = hexStrToBytes(pubKey.trim()); + + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte); + KeyFactory fac = KeyFactory.getInstance("RSA"); + Key publicKey = fac.generatePublic(keySpec); + + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, publicKey); + + byte[] forumcookie = hexStrToBytes(enc); + + byte[] plainText = cipher.doFinal(forumcookie); + + return new String(plainText); + + } catch (Exception e) { + System.err.println(e); + e.printStackTrace(System.err); + return null; + } + } + + public RSAPrivateKey getPriKey(String priKey) { + try { + byte[] pribyte = hexStrToBytes(priKey.trim()); + + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte); + KeyFactory fac = KeyFactory.getInstance("RSA"); + RSAPrivateKey key = (RSAPrivateKey) fac.generatePrivate(keySpec); + return key; + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public RSAPublicKey getPubKey(String pubKey) { + try { + byte[] pubbyte = hexStrToBytes(pubKey.trim()); + + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte); + KeyFactory fac = KeyFactory.getInstance("RSA"); + RSAPublicKey key = (RSAPublicKey) fac.generatePublic(keySpec); + return key; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public String getPri() { + return priKey; + } + + public void setPri(String pri) { + this.priKey = pri; + } + + public String getPub() { + return pubKey; + } + + public void setPub(String pub) { + this.pubKey = pub; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +}