No serializer found for class sun.security.util.Objectidentifier

Asked

Viewed 338 times

1

I have the following problem:

Error:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class sun.security.util.ObjectIdentifier and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.security.KeyPair["public"]->sun.security.rsa.RSAPublicKeyImpl["algorithmId"]->sun.security.x509.AlgorithmId["oid"])
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1191) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:312) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:71) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:33) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1396) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:913) ~[jackson-databind-2.9.6.jar:2.9.6]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:286) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:102) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:272) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:180) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:119) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:888) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:664) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.31.jar:8.5.31]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) [tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468) [tomcat-embed-core-8.5.31.jar:8.5.31]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.31.jar:8.5.31]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_171]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_171]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.31.jar:8.5.31]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_171]

Code:

@RestController
@RequestMapping(value = "/operation")
@CrossOrigin(origins = "http://localhost:4200")
public class SecurityOperationsRest {

    @Autowired
    private SecurityOperations securityOperations;

    @RequestMapping(value = "/hash", method = RequestMethod.PUT)
    public static String hash256Base64(@RequestBody String clearText) {
        return SecurityOperations.hash256Base64(clearText);
    }

    @RequestMapping(value = "/request-RSA-keys", method = RequestMethod.PUT)
    public static KeyPair generateRSAKeys(@RequestBody String sizeKey) {
        return SecurityOperations.generateRSAKeys(Integer.parseInt(sizeKey));
    }

}

Error:

PUT http://localhost:8080/Operation/request-RSA-Keys 500 ()

ERROR Error: Uncaught (in Promise): Response with status: 500 OK for URL: http://localhost:8080/Operation/request-RSA-Keys

1 answer

2


First, let’s invent a functional implementation for your method generateRSA:

public class SecurityOperations {
    public static KeyPair generateRSAKeys(int keySize) {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(keySize);
            return keyPairGenerator.genKeyPair();
        } catch (NoSuchAlgorithmException e) {
            throw new AssertionError(e);
        }
    }
}

The object KeyPair Java cannot be serialized as JSON by Jackson, so we need to assemble another object to do this. Taking a look at what’s inside the object KeyPair according to the javadocs, considering that the implementation of PublicKey will be a RSAPublicKey and that of PrivateKey will be a RSAPrivateCrtKey, the methods getEncoded() are responsible for transforming the key into an array of bytes. Other methods can also be seen as exemplified below:

public static void mostrar(KeyPair k) {
    Base64.Encoder b64e = Base64.getEncoder();
    RSAPublicKey pu = (RSAPublicKey) k.getPublic();
    RSAPrivateCrtKey pr = (RSAPrivateCrtKey) k.getPrivate();
    System.out.println("public algorithm: " + pu.getAlgorithm());
    System.out.println("public encoded: " + Arrays.toString(pu.getEncoded()));
    System.out.println("public encoded b64: " + new String(b64e.encode(pu.getEncoded()), StandardCharsets.UTF_8));
    System.out.println("public format: " + pu.getFormat());
    System.out.println("public modulus: " + pu.getModulus());
    System.out.println("public exponent: " + pu.getPublicExponent());
    System.out.println("private algorithm: " + pr.getAlgorithm());
    System.out.println("private encoded: " + Arrays.toString(pr.getEncoded()));
    System.out.println("private encoded b64: " + new String(b64e.encode(pr.getEncoded()), StandardCharsets.UTF_8));
    System.out.println("private format: " + pr.getFormat());
    System.out.println("private modulus: " + pr.getModulus());
    System.out.println("private public exponent: " + pr.getPublicExponent());
    System.out.println("private exponent: " + pr.getPrivateExponent());
    System.out.println("private prime P: " + pr.getPrimeP());
    System.out.println("private prime Q: " + pr.getPrimeQ());
    System.out.println("private prime exponent P: " + pr.getPrimeExponentP());
    System.out.println("private prime exponent Q: " + pr.getPrimeExponentQ());
    System.out.println("private CRT coefficient: " + pr.getCrtCoefficient());
}

public static void main(String[] args) {
    KeyPair kp = SecurityOperations.generateRSAKeys(2048);
    mostrar(kp);
}

Here is the output produced (probably will vary, since keys are generated randomly):

public algorithm: RSA
public encoded: [48, -126, 1, 34, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, 3, -126, 1, 15, 0, 48, -126, 1, 10, 2, -126, 1, 1, 0, -105, 64, -21, -13, 48, -41, 15, -101, 95, 88, -51, -98, 3, 87, 39, 69, 107, 34, -112, -23, 95, -115, 77, 51, -44, -76, 127, -79, -31, 54, -44, -17, -80, -41, 26, -111, 81, -110, -92, 104, -37, 18, -39, 77, -50, 112, -93, -62, -78, 20, 8, 53, 32, -127, -7, -34, -25, 47, -118, 126, -61, -84, -96, 113, -107, 125, -105, 117, 55, -128, -37, 119, 109, 83, 36, 14, 124, -118, 125, 127, 124, 74, 6, 23, 26, 101, 44, -42, -103, -115, -41, 30, -86, 124, 72, 3, -83, -93, -61, -97, 17, 2, -100, -100, 55, -56, 6, 27, 105, 50, -106, 34, 11, -124, -69, -56, 46, 103, -13, 92, -103, -81, -63, 118, -63, 85, -107, 122, -55, 7, 28, -13, 115, 115, 78, 32, 5, 27, -28, -101, -16, 56, -47, 55, -8, 110, 104, 75, -100, -54, 42, -28, -128, 48, -52, 80, -97, -20, -84, -53, -126, -54, 110, -79, 113, 107, -71, 42, -71, -123, 27, 12, 26, -80, 102, 124, 64, 100, -21, -44, 28, 38, 39, 89, -52, 37, 46, 118, 19, 43, 42, -85, 120, -128, -113, -54, -22, 7, 55, -100, 112, -105, 84, -56, 88, -67, -72, -124, 105, -12, 112, 76, -112, -117, -111, -90, 126, -92, 59, -6, 116, -111, 109, 73, 118, 86, -16, -61, 119, 79, -38, 97, -16, -125, -81, 67, 42, 71, 0, 111, 45, 126, -123, 82, 59, -14, -27, 35, 107, -60, 60, 47, -48, -117, -111, -35, 2, 3, 1, 0, 1]
public encoded b64: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl0Dr8zDXD5tfWM2eA1cnRWsikOlfjU0z1LR/seE21O+w1xqRUZKkaNsS2U3OcKPCshQINSCB+d7nL4p+w6ygcZV9l3U3gNt3bVMkDnyKfX98SgYXGmUs1pmN1x6qfEgDraPDnxECnJw3yAYbaTKWIguEu8guZ/Ncma/BdsFVlXrJBxzzc3NOIAUb5JvwONE3+G5oS5zKKuSAMMxQn+ysy4LKbrFxa7kquYUbDBqwZnxAZOvUHCYnWcwlLnYTKyqreICPyuoHN5xwl1TIWL24hGn0cEyQi5GmfqQ7+nSRbUl2VvDDd0/aYfCDr0MqRwBvLX6FUjvy5SNrxDwv0IuR3QIDAQAB
public format: X.509
public modulus: 19093998123240252180582981692150144828830602901797443454519587825183993619017054481175293838417376823489124484356227417822926340061836799578918821120350733238600269437402822692122921155415438777156119457909139578459186074935896528785696831008218655198210881466235062369049263837293988599114822903617658097938619169676862043291486270178383148786736245093111668396013934934678252254734808521433323949822262053901441665722210528585024303410822707682321439608316841995757619747917646039475558643433789028709687382507498557032525353420421280426426441628371937858875882959460301371729699031347236517313006952994100973638109
public exponent: 65537
private algorithm: RSA
private encoded: [48, -126, 4, -68, 2, 1, 0, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, 4, -126, 4, -90, 48, -126, 4, -94, 2, 1, 0, 2, -126, 1, 1, 0, -105, 64, -21, -13, 48, -41, 15, -101, 95, 88, -51, -98, 3, 87, 39, 69, 107, 34, -112, -23, 95, -115, 77, 51, -44, -76, 127, -79, -31, 54, -44, -17, -80, -41, 26, -111, 81, -110, -92, 104, -37, 18, -39, 77, -50, 112, -93, -62, -78, 20, 8, 53, 32, -127, -7, -34, -25, 47, -118, 126, -61, -84, -96, 113, -107, 125, -105, 117, 55, -128, -37, 119, 109, 83, 36, 14, 124, -118, 125, 127, 124, 74, 6, 23, 26, 101, 44, -42, -103, -115, -41, 30, -86, 124, 72, 3, -83, -93, -61, -97, 17, 2, -100, -100, 55, -56, 6, 27, 105, 50, -106, 34, 11, -124, -69, -56, 46, 103, -13, 92, -103, -81, -63, 118, -63, 85, -107, 122, -55, 7, 28, -13, 115, 115, 78, 32, 5, 27, -28, -101, -16, 56, -47, 55, -8, 110, 104, 75, -100, -54, 42, -28, -128, 48, -52, 80, -97, -20, -84, -53, -126, -54, 110, -79, 113, 107, -71, 42, -71, -123, 27, 12, 26, -80, 102, 124, 64, 100, -21, -44, 28, 38, 39, 89, -52, 37, 46, 118, 19, 43, 42, -85, 120, -128, -113, -54, -22, 7, 55, -100, 112, -105, 84, -56, 88, -67, -72, -124, 105, -12, 112, 76, -112, -117, -111, -90, 126, -92, 59, -6, 116, -111, 109, 73, 118, 86, -16, -61, 119, 79, -38, 97, -16, -125, -81, 67, 42, 71, 0, 111, 45, 126, -123, 82, 59, -14, -27, 35, 107, -60, 60, 47, -48, -117, -111, -35, 2, 3, 1, 0, 1, 2, -126, 1, 0, 10, -8, -56, -92, -31, 124, 24, 67, -69, 12, -28, 13, 124, 76, -116, 42, -70, -12, -52, -14, 64, -34, 45, 37, 127, 94, -128, -116, -44, -69, 119, -126, -45, -97, 38, -20, 55, -80, -99, -128, -123, -77, -66, 83, -88, -113, -1, 49, 22, 93, -31, -94, -120, -13, 36, -65, 8, -94, 40, 55, -67, -43, -3, -27, 127, 100, -106, -30, 7, -34, -81, 12, -32, -65, 81, 52, 67, -48, 127, -2, 9, 116, 13, 49, 11, -41, 31, 3, -118, 44, 1, -40, -43, -95, 34, 80, 49, -2, 89, 40, 102, -63, 123, -66, -47, 69, 15, 60, 89, -53, 51, -100, -48, -99, 22, 74, 21, 35, -79, 65, -100, 92, 101, 122, 73, -41, -3, 121, -57, -69, -80, -7, 78, -110, 14, -107, -87, -2, -117, -24, -95, -12, -97, -100, 37, 38, 46, -19, 90, -88, 109, 114, 15, -43, -47, -110, -49, 63, -76, 52, 43, -77, -53, 33, -79, 62, 39, -122, -56, 98, -119, -80, 125, -81, -51, -78, -15, 126, -1, -99, 77, 108, -52, 109, 27, 8, -44, 25, 33, -97, 124, -71, -126, -90, -46, -36, -36, -41, 21, -19, -124, -120, 25, 26, 21, 23, -53, -39, 49, -126, 22, 34, 82, 37, 1, 27, -103, 64, -104, 123, 46, -20, 87, 2, -62, 31, 46, -41, 41, -92, 48, -16, 13, -14, 44, 88, -101, 69, 33, 48, 25, -106, -44, -12, 27, -59, -88, 60, 27, 51, -111, -16, -127, 77, -111, -71, 2, -127, -127, 0, -24, -63, 108, -119, -24, 100, 121, 53, 72, 31, -5, 118, 38, 69, -97, 61, 108, -29, 20, -29, 88, -119, -108, 116, 34, -23, 80, -40, -22, 91, 59, 8, -112, 113, 13, 4, 114, -123, 18, 70, 79, 109, -47, 96, 32, -108, 67, -59, 72, -92, 66, 20, -107, 65, 17, -126, 12, -18, -102, 115, -114, 78, 46, -68, -81, 75, -89, 43, 82, 18, -38, 55, -125, -28, 103, -124, -86, -55, -117, 89, 76, 9, 32, -52, 123, -100, -35, -126, 16, -92, -121, 29, -2, -125, 6, -106, 10, 116, 61, -19, 17, 101, -30, 89, 19, 43, 42, 100, 116, -9, -44, -13, 6, -48, -101, 119, 76, 45, -128, -71, -89, 19, 57, 53, -7, -94, 61, 47, 2, -127, -127, 0, -90, 91, -42, 68, -68, 24, 90, -51, 50, -108, 106, -36, 116, 11, -31, -77, -93, 111, -119, 16, -15, -5, 112, -128, -86, 101, -30, -101, -11, -97, 11, 61, 48, -103, -39, 36, 50, -74, 92, -121, -107, 53, 2, 54, 75, -70, -49, 25, -87, -56, 36, 102, -98, -107, 73, -35, -50, -98, 31, -106, -15, 99, -23, 118, 105, -115, 91, 4, 51, 66, 76, 33, 67, -39, 18, 105, 37, -17, -47, 91, 19, -43, -109, 28, -5, -33, -3, 60, -64, 14, 11, 118, -128, -94, -21, -35, 120, 125, 77, 93, -37, 114, -73, 20, 59, -83, 122, 70, 3, 20, -4, -28, -109, -70, 96, -104, -87, -85, -7, -106, -75, -123, -6, 118, -76, 3, 86, -77, 2, -127, -128, 8, 118, -104, 10, -65, -81, 127, -108, -57, 101, -102, 80, 38, 126, 27, -105, 49, 49, 100, -98, 11, -89, 29, 5, -56, 11, 49, -52, 97, 97, 37, -39, 94, -33, 45, 120, -2, -19, 5, -56, 22, -75, 72, -118, -75, 68, -114, -34, 74, -112, -26, 114, 55, 39, 33, -118, -40, 11, -119, 4, 48, -91, 121, 31, -107, 68, 43, -12, -16, 76, 13, 49, 61, -109, 125, -116, 30, 101, -85, -78, 120, -120, 80, 111, -1, 2, -86, 47, 67, -119, -89, -4, 24, 56, 13, 114, 65, 57, 14, -45, 98, -15, -112, 116, 106, -75, 4, 26, -103, 2, 53, -11, 12, 71, 99, -113, -57, -18, 83, -94, -20, -121, 79, 106, 62, 4, 127, 51, 2, -127, -128, 110, -74, -16, 3, 14, -85, -90, -62, -87, -58, -36, -41, -102, -29, -51, 114, 32, 115, 58, 101, 108, -90, 74, 89, 87, 14, 55, -94, 83, -11, 101, 37, 116, 18, -17, -48, -121, 111, -106, 101, 37, -120, 1, -48, -32, -43, -110, -65, 33, -97, 113, -102, 90, 48, 64, -40, -67, -119, -66, -68, 86, 42, -120, 85, -90, 41, -51, 73, 30, 84, 33, 22, -126, 113, 21, 47, -91, 111, -43, -123, 39, -50, 27, -6, 78, 38, -28, 2, 106, 78, -18, -110, 15, 74, 94, 111, 38, -95, 61, -68, 25, 48, 95, 103, -73, -49, -36, 112, 123, -36, -101, -14, 3, -33, 38, 42, 115, -63, 96, 122, 76, -108, -67, -4, 2, 17, -74, -63, 2, -127, -128, 55, -34, 14, 14, 81, -114, 43, 103, 33, 91, 26, 24, -9, 4, 80, 117, 20, -66, 124, -27, -31, 121, -88, -92, -42, 77, 25, -57, -76, 25, -37, -28, 31, 110, 46, 101, -2, 121, 9, -48, -33, -101, -53, -54, -127, 16, -75, 10, 20, -27, -68, 16, 25, -85, -26, -90, -26, 56, 112, 61, 64, -68, -120, 127, -89, -66, 21, -59, 12, -19, -49, 26, -58, -81, -70, 15, -111, -104, 58, -92, 2, 76, 119, 36, 107, 94, 52, 127, 82, -19, -17, 106, -119, -56, -113, -50, 85, 40, -79, -47, -64, 66, 9, 8, -56, 69, 57, -128, 67, -46, 82, -4, -122, 82, -116, -1, -33, 67, -35, -27, 56, -25, 64, 16, -68, 59, -65, 91]
private encoded b64: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCXQOvzMNcPm19YzZ4DVydFayKQ6V+NTTPUtH+x4TbU77DXGpFRkqRo2xLZTc5wo8KyFAg1IIH53ucvin7DrKBxlX2XdTeA23dtUyQOfIp9f3xKBhcaZSzWmY3XHqp8SAOto8OfEQKcnDfIBhtpMpYiC4S7yC5n81yZr8F2wVWVeskHHPNzc04gBRvkm/A40Tf4bmhLnMoq5IAwzFCf7KzLgspusXFruSq5hRsMGrBmfEBk69QcJidZzCUudhMrKqt4gI/K6gc3nHCXVMhYvbiEafRwTJCLkaZ+pDv6dJFtSXZW8MN3T9ph8IOvQypHAG8tfoVSO/LlI2vEPC/Qi5HdAgMBAAECggEACvjIpOF8GEO7DOQNfEyMKrr0zPJA3i0lf16AjNS7d4LTnybsN7CdgIWzvlOoj/8xFl3hoojzJL8Ioig3vdX95X9kluIH3q8M4L9RNEPQf/4JdA0xC9cfA4osAdjVoSJQMf5ZKGbBe77RRQ88WcsznNCdFkoVI7FBnFxleknX/XnHu7D5TpIOlan+i+ih9J+cJSYu7VqobXIP1dGSzz+0NCuzyyGxPieGyGKJsH2vzbLxfv+dTWzMbRsI1Bkhn3y5gqbS3NzXFe2EiBkaFRfL2TGCFiJSJQEbmUCYey7sVwLCHy7XKaQw8A3yLFibRSEwGZbU9BvFqDwbM5HwgU2RuQKBgQDowWyJ6GR5NUgf+3YmRZ89bOMU41iJlHQi6VDY6ls7CJBxDQRyhRJGT23RYCCUQ8VIpEIUlUERggzumnOOTi68r0unK1IS2jeD5GeEqsmLWUwJIMx7nN2CEKSHHf6DBpYKdD3tEWXiWRMrKmR099TzBtCbd0wtgLmnEzk1+aI9LwKBgQCmW9ZEvBhazTKUatx0C+Gzo2+JEPH7cICqZeKb9Z8LPTCZ2SQytlyHlTUCNku6zxmpyCRmnpVJ3c6eH5bxY+l2aY1bBDNCTCFD2RJpJe/RWxPVkxz73/08wA4LdoCi6914fU1d23K3FDutekYDFPzkk7pgmKmr+Za1hfp2tANWswKBgAh2mAq/r3+Ux2WaUCZ+G5cxMWSeC6cdBcgLMcxhYSXZXt8teP7tBcgWtUiKtUSO3kqQ5nI3JyGK2AuJBDCleR+VRCv08EwNMT2TfYweZauyeIhQb/8Cqi9Diaf8GDgNckE5DtNi8ZB0arUEGpkCNfUMR2OPx+5TouyHT2o+BH8zAoGAbrbwAw6rpsKpxtzXmuPNciBzOmVspkpZVw43olP1ZSV0Eu/Qh2+WZSWIAdDg1ZK/IZ9xmlowQNi9ib68ViqIVaYpzUkeVCEWgnEVL6Vv1YUnzhv6TibkAmpO7pIPSl5vJqE9vBkwX2e3z9xwe9yb8gPfJipzwWB6TJS9/AIRtsECgYA33g4OUY4rZyFbGhj3BFB1FL585eF5qKTWTRnHtBnb5B9uLmX+eQnQ35vLyoEQtQoU5bwQGavmpuY4cD1AvIh/p74VxQztzxrGr7oPkZg6pAJMdyRrXjR/Uu3vaonIj85VKLHRwEIJCMhFOYBD0lL8hlKM/99D3eU450AQvDu/Ww==
private format: PKCS#8
private modulus: 19093998123240252180582981692150144828830602901797443454519587825183993619017054481175293838417376823489124484356227417822926340061836799578918821120350733238600269437402822692122921155415438777156119457909139578459186074935896528785696831008218655198210881466235062369049263837293988599114822903617658097938619169676862043291486270178383148786736245093111668396013934934678252254734808521433323949822262053901441665722210528585024303410822707682321439608316841995757619747917646039475558643433789028709687382507498557032525353420421280426426441628371937858875882959460301371729699031347236517313006952994100973638109
private public exponent: 65537
private exponent: 1385062896957202173832972137334357515849988345440667808761251209559862454259533957970418952772269243616084010538009142077455358357171859334394007592751382971700042432601629904914054155253444557221114666568504044371804791190400111354611940348399705308639311083670010627621957066733228890553303753357620071068234175206467715071430957112047097648304499050663377930133554042365863403753737570076381030070520699317037698947196347863859272622193490216279446699486953429387881067902697902595959388326081303450064822132405216055743367243667023940226146997997801295602085346286980230520369315767210190391626311296904332153273
private prime P: 163446514321073004442310556270960412203771433624655158721006609579827500850107863546845692572650063382225022074429964559294811733212783258552058786426329332982667733134837610861879996684888893357686279366658034746022149419467787909834301728035554629464902772892485459762980590312425691200796671107481328565551
private prime Q: 116821078764225937786358391100274496338962030684783660691596546694640594900960832456149362059936965037369846024219972954264378122562644595349923871054066112124223881181817170214143427412259330933217289911677576420863099026572813515624324206650665200409325298134954454748913677165300046201395480989434281940659
private prime exponent P: 5943101509484977487312908060999109850642954763378751594246894893399590071651235772649545835186613684481166785226156301704373657021927499048317074142147837107247771610850634400168760121764655581905891385488290535114069641066752194777532401817427204205484891096675051507014095041190631584166172806950699695923
private prime exponent Q: 77746435927498642026485917668333497601662693293063828749022307713710487010395771372009865810247809131786978412078342621316128541033192039165391756715964227023057948969683349803318426690466499503840659730957004030888886081801117449646314671060247087615440624432826853507615834463611804249814079052064721319617
private CRT coefficient: 39231423826464180962220915291000320841879655929334305881366464052655074878611840446781910148747551748349989044895551744049159735078739671304472930837060362338022547504311898612471588078035380996563722887816479784108365174533582035576898575410992828487201106190178397938016504118904196690718456301943464378203

Although seeing this pile of information is actually cool, what you really need is just the methods getEncoded(). However, you still need to be able to rebuild the KeyPair from these byte arrays. For ease, as you can see in the code, I am already using Base64 to convert the byte[] in a String that can be easily transported in JSON.

So to rebuild the KeyPair from the Base64 encoded strings, you can do this in the class SecurityOperations:

private static final Base64.Decoder b64d = Base64.getDecoder();
private static final KeyFactory keyFactory;

static {
    try {
        keyFactory = KeyFactory.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
        throw new AssertionError(e);
    }
}

private static RSAPublicKey rebuildPublicKey(String base64key) {
    try {
        byte[] b = b64d.decode(base64key.getBytes(StandardCharsets.UTF_8));
        return (RSAPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(b));
    } catch (InvalidKeySpecException e) {
        throw new IllegalArgumentException(e);
    }
}

private static RSAPrivateCrtKey rebuildPrivateKey(String base64key) {
    try {
        byte[] b = b64d.decode(base64key.getBytes(StandardCharsets.UTF_8));
        return (RSAPrivateCrtKey) keyFactory.generatePrivate(new PKCS8EncodedKeySpec(b));
    } catch (InvalidKeySpecException e) {
        throw new IllegalArgumentException(e);
    }
}

public static KeyPair rebuildKey(String base64PublicKey, String base64PrivateKey) {
    return new KeyPair(rebuildPublicKey(base64PublicKey), rebuildPrivateKey(base64PrivateKey));
}

Having then how to convert the KeyPair in two strings and vice versa, we use a class to group them:

public final class EncodedKeyPair {
    private static final Base64.Encoder b64e = Base64.getEncoder();
    private final String base64PublicKey;
    private final String base64PrivateKey;

    public EncodedKeyPair(KeyPair kp) {
        this.base64PublicKey = new String(b64e.encode(kp.getPublic().getEncoded()), StandardCharsets.UTF_8);
        this.base64PrivateKey = new String(b64e.encode(kp.getPrivate().getEncoded()), StandardCharsets.UTF_8);
    }

    @JsonCreator
    public EncodedKeyPair(
            @JsonProperty("base64PublicKey") int base64PublicKey,
            @JsonProperty("base64PrivateKey") int base64PrivateKey)
    {
        this.base64PublicKey = base64PublicKey;
        this.base64PrivateKey = base64PrivateKey;
    }

    public KeyPair rebuild() {
        return SecurityOperations.rebuildKey(base64PublicKey, base64PrivateKey);
    }
}

Jackson uses attribute-based serialization, without making use of getters and setters. For the desirialization, Jackson will use the builder annotated with @JsonCreator.

To test all this:

public static void main(String[] args) {
    KeyPair kp = SecurityOperations.generateRSAKeys(2048);
    mostrar(kp);
    System.out.println();
    mostrar(new EncodedKeyPair(kp).rebuild());
}

And you will notice that the two exits are the same.

See this working on Coding Ground.

Finally, you make this alters the method generateRSAKeys on your controller:

@RequestMapping(value = "/request-RSA-keys", method = RequestMethod.PUT)
public static EncodedKeyPair generateRSAKeys(@RequestBody String sizeKey) {
    return new EncodedKeyPair(SecurityOperations.generateRSAKeys(Integer.parseInt(sizeKey)));
}

And in your controller, you can delete this:

@Autowired
private SecurityOperations securityOperations;

The reason is that the SecurityOperations does not need to be injected, since you use its static methods instead of using an instance managed by Spring.

Finally, I make an important observation: Export the private key (which is inside the KeyPair) is almost always a bad idea. Ideally, you should not export the private key ever! Only the public key should be exported.

  • I understand. I made it very simple. The idea is a site to generate pairs of RSA keys. For now I’m doing it simply to see it working. With time adding more security protections. I ended up doing this way, I created a new object but only with the items I will use. I will have to do with all the same. I think I could encrypt the private key so that the user decrypts afterwards.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.