EJBCA操作说明(二)java操作

2023-11-18

ejbca web界面操作

代码下载地址

  • 初始化获得EJBCA实例
	/**
	 * 初始化EjbcaWS,获得EJBCA服务端Webservice实例
	 * @return
	 */
	public static EjbcaWS init() 
	{		
		EjbcaWS ejbcaWS = null;
		CryptoProviderTools.installBCProvider();
		System.setProperty("javax.net.ssl.keyStore","C:/Users/mango/Desktop/superadmin.p12");
		System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
		Provider tlsProvider = new TLSProvider();
		Security.addProvider(tlsProvider);
		Security.setProperty("ssl.TrustManagerFactory.algorithm", "AcceptAll");
		System.setProperty("javax.net.ssl.keyStorePassword", "e9a7d6bb701cfba8b0f20de5b8e92d1cf9c1f4f0");
		try 
		{
			KeyManagerFactory.getInstance("NewSunX509");
		} 
		catch (NoSuchAlgorithmException e1) 
		{	
			e1.printStackTrace();
		}
		Security.setProperty("ssl.KeyManagerFactory.algorithm", "NewSunX509");
 
		QName qname = new QName("http://ws.protocol.core.ejbca.org/","EjbcaWSService");
		EjbcaWSService service = null;
		try {
			service = new EjbcaWSService(new URL("https://ejbcatest:8443/ejbca/ejbcaws/ejbcaws?wsdl"), qname);
			ejbcaWS = service.getEjbcaWSPort();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		return ejbcaWS;
	}

采用域名的方式访问EJBCA服务端,则需要在客户端所在服务器hosts文件中加入服务器域名和IP。

 

  • 注册和更新终端实体

 

	/**
	 * 
	* @Title: editUser
	* @Description: 添加用户实例或更新用户实体
	* @param @param ejbcaWS
	* @param @param userName
	* @param @param passWord
	* @param @param caName
	* @param @throws ApprovalException_Exception
	* @param @throws AuthorizationDeniedException_Exception
	* @param @throws CADoesntExistsException_Exception
	* @param @throws EjbcaException_Exception
	* @param @throws UserDoesntFullfillEndEntityProfile_Exception
	* @param @throws WaitingForApprovalException_Exception
	* @param @throws IllegalQueryException_Exception
	* @param @throws EndEntityProfileNotFoundException_Exception    参数
	* @return void    返回类型
	* @throws
	 */
public static void  editUser(EjbcaWS ejbcaWS, String userName, String passWord, String caName, String certType) throws ApprovalException_Exception, AuthorizationDeniedException_Exception,
CADoesntExistsException_Exception, EjbcaException_Exception, UserDoesntFullfillEndEntityProfile_Exception,
 WaitingForApprovalException_Exception, IllegalQueryException_Exception, EndEntityProfileNotFoundException_Exception {

  // Test to add a user.
       final UserDataVOWS user = new UserDataVOWS();
       user.setUsername(userName);
       user.setPassword(passWord);
       user.setClearPwd(true);
       user.setSubjectDN("CN=" + userName);
       user.setCaName(caName);
       user.setEmail(null);
       user.setSubjectAltName(null);
       user.setStatus(EndEntityConstants.STATUS_NEW);
       user.setTokenType(certType);
       user.setEndEntityProfileName("EMPTY");
       user.setCertificateProfileName("ENDUSER");
       String pattern = "yyyy-MM-dd HH:mm:ssZZ"; // ISO 8601标准时间格式
       user.setStartTime(DateFormatUtils.format(new Date(),pattern));//证书有效起始日期
       user.setEndTime(DateFormatUtils.format(DateUtils.addDays(new Date(), 100), pattern));//结束日期

       ejbcaWS.editUser(user);


   }
  • 查找终端实体
  • 		/**
    		 * 检查用户实体是否存在
    		 * @param ejbcaWS
    		 * @param username
    		 * @return
    		 * @throws Exception
    		 */
    		public static boolean isExist(EjbcaWS ejbcaWS, String username) throws Exception {
    	    UserMatch usermatch = new UserMatch();
    	    usermatch.setMatchwith(UserMatch.MATCH_WITH_USERNAME);
    	    usermatch.setMatchtype(UserMatch.MATCH_TYPE_EQUALS);
    	    usermatch.setMatchvalue(username);
    	    try 
    	    {
    	        List<UserDataVOWS> users = ejbcaWS.findUser(usermatch);
    	        if (users != null && users.size() > 0) 
    	        {
    	            return true;
    	        } 
    	        else 
    	        {
    	            return false;
    	        }
    	    } 
    	    catch (Exception e) 
    	    {
    	        throw new Exception("检查用户 " + username + " 是否存在时出错:" + e.getMessage());
    	    }
    	}

     

  • 吊销并删除终端实体

     
        /**
         *
         * @Title: revokeUser
         * @Description: 吊销证书
         * @param @param ejbcaWS
         * @param @param userName
         * @return void    返回类型
         * @throws
         */
    	public static void revokeUser(EjbcaWS ejbcaWS, String userName) throws Exception 
    	{
    	
    	    // Revoke and delete
    		ejbcaWS.revokeUser(userName, RevokedCertInfo.REVOCATION_REASON_KEYCOMPROMISE, true);
    	
    	    UserMatch usermatch = new UserMatch();
    	    usermatch.setMatchwith(UserMatch.MATCH_WITH_USERNAME);
    	    usermatch.setMatchtype(UserMatch.MATCH_TYPE_EQUALS);
    	    usermatch.setMatchvalue(userName);
    	    List<UserDataVOWS> userdatas = ejbcaWS.findUser(usermatch);
            if (userdatas != null && userdatas.size() > 0) 
            {
                System.out.println("revoke failed!");
            } 
            else 
            {
            	
            	System.out.println("revoke successfully!");
            }	
    	}

     

true表示是否删除用户。

 

  • 获取证书
	public static List<Certificate> findCert(EjbcaWS ejbcaWS, String certName) throws AuthorizationDeniedException_Exception, EjbcaException_Exception
	{
		//第一个入参为实体名还是证书名?, 	End entity
		   List<Certificate> foundcerts = ejbcaWS.findCerts(certName, true);
		   return foundcerts;
	}
	

获取某个终端实体的所有证书,true表示只查找有效的证书。

	public static List<Certificate> getLastCAChainCert(EjbcaWS ejbcaWS, String caName) throws AuthorizationDeniedException_Exception, EjbcaException_Exception, CADoesntExistsException_Exception
	{
		   //入参为CA名 
		   List<Certificate> foundcerts = ejbcaWS.getLastCAChain(caName);
		   return foundcerts;
	}

根据证书16进制序列号及颁发者DN获取证书。

	public static Certificate getCert(EjbcaWS ejbcaWS, String certSNinHex, String issuerDN) throws AuthorizationDeniedException_Exception, EjbcaException_Exception, CADoesntExistsException_Exception
	{
		//第一个入参为证书序列号,第二个参数为颁发者DN
		Certificate foundcerts = ejbcaWS.getCertificate(certSNinHex, issuerDN);
		return foundcerts;
	}
	
  • 申请证书

根据已注册终端实体申请包含公私钥及证书的pkcs12文件

/**
	 * 
	* @Title: createCert
	* @Description: 根据用户实体名称密码申请pkcs12证书
	* @param @param ejbcaWS
	* @param @param username
	* @param @param password
	* @param @param path
	* @param @throws Exception    参数
	* @return void    返回类型
	* @throws
	 */
	public static void createCert(EjbcaWS ejbcaWS,String username, String password, String path) throws Exception {
	    FileOutputStream fileOutputStream = null;
	    try {
	        // 创建证书文件
	        KeyStore ksenv = ejbcaWS.pkcs12Req(username, password, null, "2048", AlgorithmConstants.KEYALGORITHM_RSA);
	        java.security.KeyStore ks = KeyStoreHelper.getKeyStore(ksenv.getKeystoreData(), "PKCS12", password);
	        fileOutputStream = new FileOutputStream(path + File.separator + username + ".p12");
	        ks.store(fileOutputStream, password.toCharArray());

	        // 创建密码文件
	        File pwdFile = new File(path + File.separator + username + ".pwd");
	        pwdFile.createNewFile();
	        BufferedWriter out = new BufferedWriter(new FileWriter(pwdFile));
	        out.write(password);
	        out.flush();
	        out.close();
	    } catch (Exception e) {
	        throw new Exception("用户  " + username + " 证书创建失败:" + e.getMessage());
	    } finally {
	        if (fileOutputStream != null) {
	            try {
	                fileOutputStream.close();
	            } catch (IOException e) {
	            }
	        }
	    }
	}

根据CSR请求申请pem格式证书

certificateResponse = ejbcaWS.certificateRequest(userDataVOWS, pkcs10AsBase64, CertificateHelper.CERT_REQ_TYPE_PKCS10, null, CertificateHelper.RESPONSETYPE_CERTIFICATE);

userDataVOWS:用户信息,用户名必填

pkcs10AsBase64: CSR请求

同一个用户可以创建多份证书,与web界面申请证书规则不同。

 

  • 吊销证书
    /**
     * @param  issuerDN 颁发者DN
     * @param  reason 吊销证书的原因
     * @return List<Certificate>  查询到的证书列表
     * @throws
     * @Title: revokeUser
     * @Description: 吊销证书
     */
    public static void revokeCert(final String issuerDN, final String certificateSN, final int reason) throws Exception {
        //第一个入参为证书颁发者DN,第二个参数为证书序列号
        ejbcaWS.revokeCert(issuerDN, certificateSN, reason);

    }

 

  • 获取证书吊销列表
   /**
     * 
    * @Title: getCRL
    * @Description: 获取某个CA的证书吊销列表
    * @param @param ejbcaWS
    * @param @param caName	CA名称
    * @param @param delta	是否为增量
    * @param @return
    * @param @throws CADoesntExistsException_Exception
    * @param @throws EjbcaException_Exception
    * @param @throws CRLException    参数
    * @return int    返回类型
    * @throws
     */
    public static Set<? extends X509CRLEntry> getCRL(EjbcaWS ejbcaWS, final String caName, final boolean delta) throws CADoesntExistsException_Exception, EjbcaException_Exception, CRLException {
        final byte[] crlBytes = ejbcaWS.getLatestCRL(caName, delta);
        if(crlBytes == null)
        {
        	return null;
        }
        final X509CRL crl = CertTools.getCRLfromByteArray(crlBytes);
        final Set crls = crl.getRevokedCertificates();
        final BigInteger crlNumber = CrlExtensions.getCrlNumber(crl);
        System.out.println(crl.getIssuerDN());
        System.out.println(crl.getThisUpdate());
        System.out.println(crl.getNextUpdate());
        System.out.println(crlNumber.intValue());
        X509CRLEntry entry = crl.getRevokedCertificate(new BigInteger("8805361580365352127"));
        if (entry != null) {
            String time = new SimpleDateFormat("yyyyMMddHHmmss").format(entry.getRevocationDate());
            System.out.println(entry.getSerialNumber());
            System.out.println(entry.getRevocationReason());
            System.out.println(entry.getCertificateIssuer());
        }

        
        return crls;
    }

注意CA的CRL列表不能实时更新,有滞后性,一般一天更新一次。

  • 证书验证
  • 验证证书链
 /**
     * 
    * @Title: verifyEffect
    * @Description: 验证证书链
    * @param @param ejbcaWS
    * @param @param foundcerts
    * @param @return    参数
    * @return boolean    返回类型
    * @throws
     */
    public static boolean verifyEffect(EjbcaWS ejbcaWS,List<Certificate> foundcerts){ 
        boolean effectFlag = false;
        try 
        {
        	System.out.println("foundcerts.size:"+foundcerts.size());
        	java.security.cert.Certificate cert = 
        			(java.security.cert.Certificate) CertificateHelper.getCertificate(foundcerts.get(0).getCertificateData());
			System.out.println("client SubjectDN:"+ CertTools.getSubjectDN(cert));
			System.out.println("client IssuerDN:"+ CertTools.getIssuerDN(cert));
			System.out.println("client SerialNumber:"+ CertTools.getSerialNumber(cert));
			for(int i = 1 ;i < foundcerts.size(); i++)
			{
				java.security.cert.Certificate cert2 = 
						(java.security.cert.Certificate)CertificateHelper.getCertificate(foundcerts.get(i).getCertificateData());
				System.out.println("service SubjectDN:"+ CertTools.getSubjectDN(cert2));
				System.out.println("service IssuerDN:"+ CertTools.getIssuerDN(cert2));
				System.out.println("service SerialNumber:"+ CertTools.getSerialNumber(cert2));
				cert.verify(cert2.getPublicKey());
				effectFlag = true;
			}
        }
        catch (Exception e) {
			System.out.println(e.getMessage());
		}
        return effectFlag;
        
    }

 

  • 验证证书有效性
    /**
     * <p>
     * 验证证书是否过期或无效
     * </p>
     * 
     * @param date 日期
     * @param certificate 证书
     * @return
     */
    public static boolean verifyCertificate(Date date,java.security.cert.Certificate certificate) {
        boolean isValid = true;
        try {
            X509Certificate x509Certificate = (X509Certificate)certificate;
            x509Certificate.checkValidity(date);
            System.out.println("cert valid");
        } catch (Exception e) {
        	System.out.println(e.getMessage());
            isValid = false;
        }
        return isValid;
    }

 

  • 验证签名
    
    /**
     * <p>
     * 验证签名
     * </p>
     * 
     * @param data 已加密数据
     * @param sign 数据签名[BASE64]
     * @param certificatePath 证书存储路径
     * @return
     * @throws Exception
     */
    public static boolean verifySign(byte[] data, String sign, java.security.cert.Certificate certificate) 
            throws Exception {
        // 获得证书
        X509Certificate x509Certificate = (X509Certificate) certificate;
        // 获得公钥
        PublicKey publicKey = x509Certificate.getPublicKey();
        // 构建签名
        Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
        signature.initVerify(publicKey);
        signature.update(data);
//        return signature.verify((sign));
        return true;
    }

 

  1. 遗留问题

1.EJBCA提供了JAVA SDK去调用其Webservice接口,初始化时获取了EJBCA的EjbcaWSService实例,并需要设置证书。如果使用手机客户端直接访问EJBCA的话APP是否能获得该实例,如何配置证书等。EJBCA是否提供了手机APP集成时需要使用的SDK?

2.获取Ejbca实例客户端需要配置超级管理员证书,该证书拥有删除用户,修改用户,注册CA等一系列敏感权限,如果手机直接集成的话会存在危险。目前看可以在管理员界面对该证书的权限进行配置。

3.部署环境时需要修改ejbca-setup.sh脚本中的httpsserver_hostname为部署所在服务器的主机名称,这样在生成EJBCA HTTPS服务端证书时证书Domain Name与服务器域名相同,客户端才可以通过域名正常访问。如果通过IP访问则还需要修改ejbca-setup.sh脚本。

后面我会把操作的代码打包放到资源里面,大家可以下载

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

EJBCA操作说明(二)java操作 的相关文章

  • V8 如何管理它的堆?

    我知道V8的垃圾收集在工作时 会从GC的root开始追踪 这样无法到达的对象就会被标记然后被清除 我的问题是GC是如何遍历那些对象的 必须有一个数据结构来存储所有可达或不可达的对象 位图 链接表 顺便说一句 JVM 也做同样的事情吗 艾伦秀
  • Java Swing:清除JList而不触发监听器

    我的情况如下 我有一个 JList 只要在列表中进行选择 它就会触发搜索 使用 ListSelectionListener 我正在尝试使用以下命令重置列表上的选择list clearSelection 这样做的问题是使用clearSelec
  • 有效地查找正则表达式的所有重叠匹配项

    这是后续与 java 正则表达式匹配的所有重叠子字符串 https stackoverflow com q 11303309 244526 有没有办法让这段代码更快 public static void allMatches String
  • 使用 jdbc 程序连接到 Open Office odb 文件

    我编写了以下代码来连接到 OpenOffice db String db C Documents and Settings hkonakanchi Desktop Test odb Class forName org hsqldb jdbc
  • 方法不必要地被调用?

    我有一个 BaseActivity 它可以通过其他所有活动进行扩展 问题是 每当用户离开 暂停 活动时 我都会将音乐静音 我也不再接听电话 问题是 onPause每当用户在活动之间切换时就会被调用 这意味着应用程序不必要地静音和停止tele
  • 删除 servlet 中的 cookie 时出现问题

    我尝试使用以下代码删除 servlet 中的 cookie Cookie minIdCookie null for Cookie c req getCookies if c getName equals iPlanetDirectoryPr
  • 如何正确配置Tomcat SSLHostConfig?

    我正在按照本教程在 tomcat 中启用 ssl https medium com raupach how to install lets encrypt with tomcat 3db8a469e3d2 https medium com
  • Java 的 QP 求解器 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 Spring 中设置 WS https 调用超时 (HttpsUrlConnectionMessageSender)

    我正在尝试为 WS 调用设置超时 我延长了WebServiceGatewaySupport并尝试将发送者超时设置为如下 public Object marshalSendAndReceive Object requestPayload We
  • 您能让 Tomcat 6 stdout.log 文件表现得像 log4j DailyRollingFileAppender 吗?

    我们使用的是 Tomcat 6 的 Windows 安装 默认情况下 我们应用程序的 log4j 输出将转到 catalina base logs stdout log 文件 该日志文件仅在我们重新启动 Tomcat 时滚动 并且文件名始终
  • 如何自定义JProgressBar?

    我正在制作一个启动器 我想要一个自定义的进度栏 我已经做了一些研究 并且可以使用 JavaFX 从未用它做过任何事情 并且可以通过替换 UI 来实现 我正在寻找一个具有圆形边缘和圆形填充的酒吧 像这样的事情 package gui impo
  • java JFileChooser 文件大小过滤器

    我知道我可以按文件类型进行过滤 但是可以按文件大小进行过滤吗 例如 JFileChooser 仅显示 3 MB 以内的图片 简短的回答应该是 你尝试过什么 长答案是肯定的 JFileChooser fc new JFileChooser f
  • grails 上的同步块在 Windows 上有效,但在 Linux 上无效

    我有一个 grails 应用程序 它依赖于服务中的同步块 当我在 Windows 上运行它时 同步按预期工作 但当我在 ams linux 上运行时 会出现 StaleObjectStateException 该问题在以下示例中重现 cla
  • Java中的DRY原则[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我一直在读关于DRY https en wikipedia org wiki Don 27t repeat yourself原则 虽然看起来
  • @TestPropertySource 不适用于 Spring 1.2.6 中使用 AnnotationConfigContextLoader 的 JUnit 测试

    似乎我在 Spring 4 1 17 中使用 Spring Boot 1 2 6 RELEASE 所做的任何事情都不起作用 我只想访问应用程序属性并在必要时通过测试覆盖它们 无需使用 hack 手动注入 PropertySource 这不行
  • java中的比较器链

    正在阅读Oracle 关于接口的 Java 教程 https docs oracle com javase tutorial java IandI createinterface html其中给出了一个例子Card 打牌 我试图理解接口中的
  • Android同步onSensorChanged?

    这是我的问题的后续 Android线程可运行性能 https stackoverflow com questions 36395440 android thread runnable performance 我在理解应用程序的同步方法时遇到
  • Java SE + Spring Data + Hibernate

    我正在尝试使用 Spring Data Hibernate 启动 Java SE 应用程序 并且到目前为止已经完成了以下操作 配置文件 Configuration PropertySource classpath hibernate pro
  • 使用 Android 的 Mobile Vision API 扫描二维码

    我跟着这个tutorial http code tutsplus com tutorials reading qr codes using the mobile vision api cms 24680关于如何构建可以扫描二维码的 Andr
  • 如何使用 Spring AOP 建议静态方法?

    在执行类的静态方法之前和之后需要完成一些日志记录 我尝试使用 Spring AOP 来实现这一点 但它不起作用 而对于正常方法来说它起作用 请帮助我理解如何实现这一点 如果可以使用注释来完成 那就太好了 也许您应该在使用 Spring AO

随机推荐

  • 区块链的运行流程梳理记录

    目录 0 比特币交易流程 1 生成交易 2 网络传播与验证 3 交易池管理 4 交易优先级排序 5 交易手续费定价 6 共识竞争与构建区块 7 难度调整机制 8 分叉处理与主链判断 0 比特币交易流程 从交易的生命周期来看 比特币系统的交易
  • Is Usb Drive () ? DeviceIoControl, IOCTL_STORAGE_QUERY_PROPERTY

    http banderlogi blogspot com 2011 06 enum drive letters attached for usb html typedef enum STORAGE BUS TYPE BusTypeUnkno
  • Elasticsearch 相关度评分TF&IDF算法揭秘

    1 算法介绍 relevance score算法 简单来说 就是计算出 一个索引中的文本 与搜索的文本 他们之间的关联匹配程序 ElasticSearch使用的是term frequency inverse document frequen
  • 关于C++中cout.precision()的使用以及控制输出的小数位数.

    在C 中可以使用cout precison val 来控制浮点数的输出精度 但并不是意味着仅使用cout precison val 可以控制输出结果的小数点位数 在此记录一下 就当做学习笔记 下面先做一下简单的验证 include
  • NLP学习02_最大匹配算法、UniGram LM、Spell Correction

    如果没有数据的时候 那只能通过正则或者规则来解决问题 但是有些基于概率的方法 必须有一定的数据 首先我们要对句子进行切分 使用分词 接着进行预处理 拼写纠错 stemming 将不同的单词转换到原型 停用词过滤 a an 单词顾虑 同义词等
  • win7本地服务器如何添加网站,win7 添加本地服务器地址

    win7 添加本地服务器地址 内容精选 换一换 OBS Browser 是一款用于访问和管理对象存储服务的图形化工具 支持通过配置内网DNS服务器地址的方式 使在华为云上的Windows ECS通过内网直接访问OBS 下面将介绍具体其操作流
  • java写企业员工信息管理系统

    java写企业员工信息管理系统 这一篇文章主要介绍java写的企业员工信息管理系统 功能介绍 员工登录 首页 工资信息 出差记录 请假 签到 留言 修改密码 退出登录 管理员登录 员工管理 新增员工 工资信息 出差信息 请假信息 签到信息
  • RoboMaster机甲大师:裁判系统服务器搭建助手(RMServer Aid)

    RoboMaster机甲大师 裁判系统服务器搭建助手 RMServer Aid 更新 2022 03 28 写在前面 使用教程 软件简介 软件下载 软件安装 软件使用 打开软件 首次使用 1 组建局域网 2 配置RM环境 3 启动RM服务
  • vmware 磁盘扩容

    文章目录 参考 https blog csdn net zmzdmx article details 112299741 fdisk dev sda root localhost fdisk dev sda Welcome to fdisk
  • 二. SpringCloud Alibaba Sentinel 流控

    目录 一 简单介绍 二 流控模式 直接 快速失败 关联 快速失败 三 流控效果 快速失败 WarmUp 预热 排队等待 一 简单介绍 假设当前 Sentinel 监控的服务中有两个接口 针对整个服务 或针对服务中的指定接口添加流量控制设置
  • nodejs http模块

    客户端 在网络节点中 负责消费资源的电脑 叫做客户端 服务器 负责对外提供网络资源的电脑 叫做服务器 http 模块 是node js 官方提供的 用来创建web 服务器的模块 通过http 模块提供懂得 http caeateServer
  • 自删除技术详解

    基础知识 这里首先说一下程序自删除实现的思路 程序创建一个批处理文件 并创建进程执行 然后程序结束进程 批处理所做的功能便是延时5秒后 删除指定程序然后再自删除 这样 程序自删除功能便实现了 常用的有三种 自删除 技术 1 利用window
  • esp32-S3专题二:内存1之RAM使用

    esp32 S3模块内部的存储分为ROM RAM SPRAM RTC内存 FLASH 种类很多 几乎可以不使用外接存储器的情况下 可以进行很多业务场景 十分有用 现在我们逐一讲解一下他们的作用和使用方法 一 ROM 384 KB 内部 RO
  • Obsidian学习从0到1 —— MARKDOWN

    文章目录 1 认识markdown 2 使用markdown 常用语法 1 标题 2 加粗 斜体 删除线 3 列表 4 分级 5 引用 6 分割线 7 链接 8 代码块 9 任务列表 快捷方式 10 插入图像 11 表格支持 高级用法 1
  • 【STM32】入门(十三):FreeRTOS

    STM32 STM32单片机总目录 1 FreeRTOS简述 完全免费 FreeRTOS是完全免费的实时操作系统 源码简单 只需 3 个 RTOS 移植通用的源文件和 1 个微控制器专用的源文件 镜像较小 具有最小 ROM RAM 和处理开
  • 集简云上线ChatGPT文档问答,基于文档实现智能问答训练

    过去 我们想要让ChatGPT结合自身业务进行针对性回答 只能通过输入大量的prompt提示 或使用官方原生Fine Tuning模型训练 然而 过多的prompt提示词一方面提高了使用成本 另一方面 提示词的信息量有限 无法复用于不同的问
  • Permutation 和 Combination

    文章目录 Permutation 代码 代码核心思路 Combination 代码 代码核心思路 总结 Permutation 和 Combination是算法中非常常见的两种数据的排列方式 也就是数学中的排列和组合 Permutation
  • java代码编写规范,讲的太透彻了

    什么是ACID 事务的定义和实现一直随着数据管理的发展在演进 当计算机越来越强大 它们就能够被用来管理越来越多数据 最终 多个用户可以在一台计算机上共享数据 这就导致了一个问题 当一个用户修改了数据而另外一个还在使用旧数据进行计算过程中 这
  • 符号“∑”的用法

    和 分别用来表示求和与求积 Sigma X 将X中的值全部相加 XF XF X表示的是产量 这个没有错 F表示有同样产量X的人数 数学上称为频数 就是英语的Frequency XF的意思 不是人均产量 人数 而是产量X 产量为X的人数 例如
  • EJBCA操作说明(二)java操作

    ejbca web界面操作 代码下载地址 初始化获得EJBCA实例 初始化EjbcaWS 获得EJBCA服务端Webservice实例 return public static EjbcaWS init EjbcaWS ejbcaWS nu